Walletfox.com

QSettings example for font-related widgets

This article shows how to store settings of a Qt application. The application enables to store settings of MainWindow and its two widgets, namely QFontComboBox and QSpinBox. The situation is illustrated in the figure below:


QSettings example

To store the settings we need to do the following:

  • introduce MainWindow::writeSettings()
  • override MainWindow::closeEvent() and call in it writeSettings()
  • introduce MainWindow::readSettings() and call it from the MainWindow constructor

MainWindow constructor

In the MainWindow constructor we create the widgets (QFontComboBox, QSpinBox and QToolBar that contains them) and call readSettings(). I will explain the details of readSettings() later.

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    createWidgets();
    createToolBar();
    readSettings();
}

How to implement writeSettings() and closeEvent()

In writeSettings() we construct the QSettings object. The settings will be stored in a file which we named qsettingsexample.ini in the format QSettings::IniFormat. If the file doesn't exist, it will be created and will appear in our project folder after we run the application for the first time and close it.

void MainWindow::writeSettings(){
    //QSettings settings("Walletfox", "QSettings example");
    QSettings settings("qsettingsexample.ini", QSettings::IniFormat);

    settings.beginGroup("mainwindow");
    settings.setValue("size", this->size());
    settings.endGroup();

    settings.beginGroup("text");
    settings.setValue("font", this->fontComboBox->currentFont());
    settings.setValue("size", this->fontSizeSpinBox->value());
    settings.endGroup();
}
A common method of constructing QSettings is passing the name of the company and the name of the project (commented out in the code). This line of code also saves the settings, however in a platform-specific location (not in the project or application folder!). Normally, you do not have to look for it or even know its name, as by calling readSettings() the settings will be retrieved from the very same location. If you want to know where it is, you can call settings.fileName() with qDebug().
QSettings are internally implemented as a Monostate. In a Monostate design pattern all data members of a class are static, so regardless of how many instances of QSettings are created, each instance uses the same data.

Next, the function writeSettings() contains two groups of settings, I named them "mainwindow" and "text". Both of the groups have their subsettings. We output the subsettings by creating a group and then calling setValue(key, value). There is another way of handling subsettings with the use of slash. In such a case you do not need to create a group. You can see this below:

Original implementation:

settings.beginGroup("mainwindow");
settings.setValue("size", this->size());
settings.endGroup();

Alternative implementation:

settings.setValue("mainwindow/size", this->size());

Next, we override closeEvent() and call in it writeSettings(). This enables to store the settings after we close the window.

void MainWindow::closeEvent(QCloseEvent *event){
    writeSettings();
    QMainWindow::closeEvent(event);
}

How to implement readSettings()

In readSettings() we retrieve the settings from the file and set the widget parameters to what we retrieved. To retrieve the values we use settings.value(key, defaultValue). The function returns the values as QVariant. These values need to be converted to their specific types with toSize(), toInt(), value<QFont>(). Notice also, that we introduced some default values for the case there is no configuration file, e.g. the default font size is 10.

void MainWindow::readSettings(){
    //QSettings settings("Walletfox", "QSettings example");
    QSettings settings("qsettingsexample.ini", QSettings::IniFormat);

    resize(settings.value("mainwindow/size", QSize(250,200)).toSize());
    this->fontComboBox->setCurrentFont(
                  settings.value("text/font", QFont()).value<QFont>());
    this->fontSizeSpinBox->setValue(settings.value("text/size", 10).toInt());
}

That's it! To try out the example you need to do the following:

1. Run the example for the first time, change the values in the widgets and exit the application. You should see that a configuration file appeared in your project folder.
2. Rerun the application, you should see that the application loaded the new settings.

Tagged: Qt