Trolltech Home | Qt-jambi-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-jambi-interest Archive, September 2007
QMainWindow#restoreState() does not restore state


Message 1 in thread

Hi!

I'm facing the following problem: I'm saving the main window state information 
when the window is closed and attempt to load it if present when the window 
is opened. This is the code I use for loading the state:

        // restore main window state
        try {
            File stateFile=new 
File(State.getInstance().getPreferencesManager().getUserPreferencesPath() + 
frameLayout.getName() + ".state");
            FileInputStream input=new FileInputStream(stateFile);
            byte[] tempData=new byte[input.available()];
			input.read(tempData);
	        QByteArray data=new QByteArray();
	        restoreState(data);
		} catch (IOException e) {
			/* Do nothing here because file is not guaranteed to exist or be correct.
			 * This results in the use of the default layout, which should be done
			 * silently.
			 */
		}

And this is for saving:

    @Override
	public void closeEvent(QCloseEvent event) {
		
ml.core.State.getInstance().getUIManager().unregisterApplicationWindow(this);
		// replace layout in UIManager with this layout
		State.getInstance().getUIManager().addOrReplaceLayout(frameLayout);

		// save main window state
        try {
            File stateFile=new 
File(State.getInstance().getPreferencesManager().getUserPreferencesPath() + 
frameLayout.getName() + ".state");
            stateFile.delete();
            FileOutputStream output= new FileOutputStream(stateFile);
	        QByteArray data=saveState();
			output.write(data.toByteArray());
		} catch (IOException e) {
			/* Do nothing here because a failure to save the dock widget state
			 * only means that the layout state will be reset to defaults the
			 * next time the window is opened.
			 */
		}

		dispose();
    }

I have tried to debug these two pieces of code and find nothing wrong with 
them. The data that gets passed from saveState() is saved to a file with 
correct length and also loaded completely and passed to restoreState() when 
the window is open. Also, the code to restore state runs after all widgets in 
the window have been created. But when the main window opens up I always get 
a default dock widget arrangement instead of the one I had when closing the 
window. Can you spot an issue in this code which might cause this behaviour? 
Thanks!

Regards,
Gregor

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 2 in thread

Gregor Mückl wrote:
> Hi!
> 
> I'm facing the following problem: I'm saving the main window state information 
> when the window is closed and attempt to load it if present when the window 
> is opened. This is the code I use for loading the state:
 >
> 
>         // restore main window state
>         try {
>             File stateFile=new 
> File(State.getInstance().getPreferencesManager().getUserPreferencesPath() + 
> frameLayout.getName() + ".state");
>             FileInputStream input=new FileInputStream(stateFile);
>             byte[] tempData=new byte[input.available()];
> 			input.read(tempData);
> 	        QByteArray data=new QByteArray();
> 	        restoreState(data);

Hi Gregor,

You're not passing the data read from the file (tempData) to the actual 
byte array, so you restore the data based on an empty data buffer... 
This is will not work ;-).

It is also important to name the objects, using setObjectName(), so that 
the restore/save State function can properly recognize the objects. Its 
possible that you already have this in place but I couldn't tell from 
the code.

Finally... Qt offers a significantly easier way of storing preferences 
using QSettings. Instead of the File / Stream / read logic you should 
only do:

         QSettings settings = new QSettings("MySoft", "testing");
         QByteArray array = saveState();
         settings.setValue("state", array);

for saving an to restore:

         QSettings settings = new QSettings("MySoft", "testing");
         QByteArray state = (QByteArray) settings.value("state");
         restoreState(state);


I attached a complete example.

-
best regards,
Gunnar
package com.trolltech.tests;
package com.trolltech.tests;

import com.trolltech.qt.core.*;
import com.trolltech.qt.gui.*;

class MainWindowState extends QMainWindow {

    public MainWindowState() {
        QDockWidget w1 = new QDockWidget();
        w1.setWindowTitle("Dock 1");
        w1.setObjectName("a");

        QDockWidget w2 = new QDockWidget();
        w2.setWindowTitle("Dock 2");
        w2.setObjectName("b");

        addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, w1);
        addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, w2);

        setCentralWidget(new QTextEdit());
    }


    protected void hideEvent(QHideEvent e) {
        QSettings settings = new QSettings("MySoft", "testing");
        QByteArray array = saveState();
        settings.setValue("state", array);
    }


    protected void showEvent(QShowEvent e) {
        QSettings settings = new QSettings("MySoft", "testing");
        QByteArray state = (QByteArray) settings.value("state");
        restoreState(state);
    }

    public static void main(String args[]) {
        QApplication.initialize(args);
        
        MainWindowState widget = new MainWindowState();
        widget.show();
        
        QApplication.exec();
    }
}