Restoring Qt Application State and Geometry: Part 3

Read the Second Tutorial

So by now we have a complete application, but I’d like to pull out a few extra tricks. Primarily, I want to make the application store the state even if there isn’t any user interaction. This could be very useful if your application is a complex GUI comprised of several toolbars, etc. By implementing a continuous loop of state storage, even if your application crashes, the data will be preserved from a certain amount of time before. We’ll need to change a few things first, however, starting with the MainWindow declaration:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSettings>
#include <QByteArray>
#include <QTimer>

namespace Ui
{
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    // Method to get milliseconds out of seconds
    inline int secondsToMilliseconds(const int &seconds)
    {
        return seconds * 100;
    }

protected:
    void closeEvent(QCloseEvent *);

private slots:
    void on_actionQuit_triggered();

    // Some functions we will use for restoring/writing the
    // necessary data

    // We have to move these to slots so they can be
    // fired off when signals are emitted.
    void writeSettings();
    void readSettings();
    void restore();

    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    QSettings *appSettings;
    QTimer *saveTimer;

    // Interval the timer fires in real seconds
    int savingIntervalSeconds;
};

#endif // MAINWINDOW_H

There are a few changes you can probably spot immediately. The most blatant of the changes is that we move all our settings functions from the private declarations to that of the private slots declaration. Also, there is a push button slot, which is for a Quit Without Saving button. This is just to demonstrate that the timer still saves the state even if the application is terminated in another way. Lastly, there is an integer that we store the number of seconds in, and a simple inlined function to convert that to milliseconds later for the timer–which can also be found in the private declarations as a pointer member.

Now lets take a look at the new implementation. I’m only going to show what has been changed, so this implementation will not work unless you already have the existing file.

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent), ui(new Ui::MainWindow),
    savingIntervalSeconds(10)

Notice the only thing we are really doing here is adding a simple initializer for the savingIntervalSeconds. This is just my preferred method, as you could do this in several other ways. Next is the addition of the timer, which is demonstrated in the code below:

    saveTimer = new QTimer(this);
    saveTimer->setInterval(secondsToMilliseconds(savingIntervalSeconds));
    saveTimer->start();

    // Write settings everytime this is called.
    connect(saveTimer, SIGNAL(timeout()), this, SLOT(writeSettings()));

Now the timer will loop and loop (unless you stop it, of course…) and every 10 seconds it will call writeSettings(), which saves everything you put in that function (now technically a slot, but they behave similarly). Now that it is a slot, you could also provide very easy means of users being able to control when the state is saved. For instance, a button can now more easily be connected using QObject::connect instead of more complex means.

And I do believe that concludes our tutorial series on saving state and geometry! If you have any questions/comments/thoughts, feel free to leave me a comment below or contact me via Twitter.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s