2009-04-30

Use QSettings

Normally, different applications have different ways to handle user preferences. For instance, it may be natural to choose Tcl script to save preferences for those applications that support Tcl scripting. But some specific settings, like window geometries opened last time, we don't want to trouble users to modify manually. We can choose whatever we feel convenient and they don't care about these settings.

In this case, the best way to handle this is using QSettings. In Unix platforms, QSettings put setting files under ~/.config according to application name and the organization that produces it. You may see directory structure like this,

[yenliangl@halo]:~/.config > ll total 13 drwx------ 2 yenliangl staff 512 May 16 2007 autostart/ drwxr-x--- 2 yenliangl staff 512 Apr 7 19:30 fixit/ drwx------ 2 yenliangl staff 512 Apr 30 12:28 gtk-2.0/ drwxr-x--- 2 yenliangl staff 512 Jul 17 2008 menus/ drwxr-x--- 2 yenliangl staff 512 Dec 24 16:43 Synopsys/ drwxr-xr-x 2 yenliangl staff 512 Jul 10 2007 Trolltech/ -rw------- 1 yenliangl staff 5769 Apr 22 13:47 Trolltech.conf -rw-r----- 1 yenliangl staff 242 Apr 13 18:38 Unknown Organization.conf
All Qt-related settings are located at Trolltech/ or in Trolltech.conf. How do we use QSettings? First, we let QSettings know our organization and product by,
   QCoreApplication::setOrganizationName( "SomeCompany" );
 QCoreApplication::setOrganizationDomain( "somecompany.com" );
 QCoreApplication::setApplicationName( "MyTool" );
and then, we have two private methods defined in our MainWindow class to write/read settings,
class MainWindow : public QMainWindow {
Q_OBJECT
public:
void closeEvent(QCloseEvent* e);
// ...

private:
void read_settings();
void write_settings();
// ...
};
In MainWindow::MainWindow(), we add a call to read_settings(),
MainWindow::MainWindow( /* ... */ )
{
// ...
read_settings();
}
and add a call to write_settings() as we exit application,
void MainWindow::closeEvent(QCloseEvent* e)
{
 // ...
 write_settings();
}
The definitions of read_settings() and write_settings() should look like,
void MainWindow::read_settings()
{
  QSettings settings;
  settings.beginGroup( "MainWindow" );
  restoreState( settings.value( "wm_state" ).toByteArray() ); // 可能有問題喔,如下。
  resize( settings.value( "size", QSize( 400, 400 ) ).toSize() );
  move( settings.value( "pos" ).toPoint() );
  settings.endGroup();
}

void MainWindow::write_settings()
{
  QSettings settings;
  settings.beginGroup( "MainWindow" );
  settings.setValue( "wm_state", saveState() ); // 可能有問題喔,如下。
  settings.setValue( "size", size() );
  settings.setValue( "pos", pos() );
  settings.endGroup();
}
set? not yet. If you are using QDockWidget or QToolBar in your application, we should see an error message at application run-time, saying that QDockWidget doesn't have objectName property set. From release note of Qt4, you should find,
The QMainWindow::saveState() and QMainWindow::restoreState() functions no longer fallback to using the windowTitle property when the objectName property is not set on a QToolBar or QDockWidget; this behavior was undocumented and has been removed.
It points out that you need to set objectName property manually. Simple!
myDock->setObjectName("whatever name"); // Or/And
myToolBar->setObjectName("whatever name");
Now. We're done. Run your application. You will discover your application remembers the window state and even the states of dock widgets.

沒有留言:

張貼留言