I have a problem that on Linux with Xorg (Ubuntu 14.04) and Qt 5.5.1 QSplashScreen
isn't painted until I get to the event loop. Even if I call QApplication::processEvents()
multiple times, it still isn't painted, even after 1000 calls, although the window is already on the screen, retaining the original pixels which were there before the app launched, thus being effectively invisible*. From this answer I got an idea of using a timed loop of calling QApplication::processEvents()
, like here:
#include <QThread>
#include <QApplication>
#include <QSplashScreen>
int main(int argc, char** argv)
{
QApplication a(argc,argv);
QSplashScreen splash;
splash.show();
splash.showMessage("Loading...");
// The hack to try to ensure that splash screen is repainted
for(int i=0;i<30;++i)
{
QThread::usleep(1e3);
a.processEvents();
}
QThread::usleep(5e6); // simulate slow loading process
splash.showMessage("Finished");
return a.exec();
}
The above code actively sleeps for 30 ms in an attempt to make QSplashScreen
repaint. This works for me, but I'm not sure that it'll always work e.g. on a busy/slow CPU or in whatever other conditions (the magic value of 30 iterations was found empirically).
Another, quite intrusive in general, way would be to do all the necessary loading in another thread, only to make sure that QSplashScreen
in the main thread does have an active message queue. Due to the need to considerably redo the main program, this looks not too good of a solution.
So, is there any way to make sure that QSplashScreen
has been repainted, so that its window doesn't contain garbage, and only then to proceed with long blocking loading process?
* I discovered this when I moved a window behind the splash screen