startmyappLater
Here is a simple trick you should use when starting up your Qt program. If you have read just about any of my “main.cpp” files, you may have seen it.
Ok, so say you have this:
class App : public QObject
{
Q_OBJECT
public:
App()
{
// init, do stuff, whatever
}
signals:
void quit();
};
int main(int argc, char **argv)
{
QApplication a(argc, argv);
App app;
QObject::connect(&app, SIGNAL(quit()), &a, SLOT(quit()));
a.exec ();
return 0;
}
Here’s a basic application object. It can emit quit() to end the program. The constructor does the initialization, makes QWidgets, etc, and off you go.
However, there is a subtle problem. The Qt eventloop is not active during App’s constructor! The eventloop begins only once exec is called. Here are the snags of this pre-eventloop phase:
1) You can’t call any functions that require the eventloop to already exist. For example, I believe QObject::deleteLater() does nothing if the loop hasn’t started. I don’t know if you can use QTimer objects either (singleshots, however, are allowed. see below).
2) You can’t exit via QCoreApplication::quit(). This means if you decide during your initialization that you want to exit, you can’t. You need to wait for the eventloop to begin before you can do that.
We can fix this with a QTimer singleshot, an operation that fortunately does work in this phase. We simply create a start() slot in App, and set a singleshot on it from main().
class App : public QObject
{
Q_OBJECT
public slots:
void start()
{
// init, do stuff, whatever
}
signals:
void quit();
};
int main(int argc, char **argv)
{
QApplication a(argc, argv);
App app;
QObject::connect(&app, SIGNAL(quit()), &a, SLOT(quit()));
QTimer::singleShot(0, &app, SLOT(start()));
a.exec ();
return 0;
}
That’s it! Now you can do your major initialization inside start(), with the assurance that all code inside there will work as expected.


