Search code examples
qtc++11qt5qtimer

QSplashScreen disappears too quickly


I am trying to show a QSplashScreen before launching my application. The problem I have is that the QSplashScreen disappears too quickly. I would like it to show for 2 seconds before the real application loads. Below the small example I built to show the error:

#include <QApplication>
#include <QSplashScreen>
#include <QTimer>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QSplashScreen *splash = new QSplashScreen;
    splash->setPixmap(QPixmap(":/dredgingSplash.png"));
    splash->show();
    Qt::Alignment topRight = Qt::AlignRight | Qt::AlignTop;
    splash->showMessage(QObject::tr("Setting up the main window..."), topRight, Qt::white);

    QTimer::singleShot(2500, splash, SLOT(close()));
    MainWindow w;
    QTimer::singleShot(2500, &w, SLOT(show()));

    splash->showMessage(QObject::tr("loading modules..."), topRight, Qt::white);
    splash->showMessage(QObject::tr("Establishing Connections..."), topRight, Qt::white);

    w.show();
    delete splash;
    return a.exec();
}

EDITS using QSplashScreen::finish() from official documentation:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QSplashScreen *splash = new QSplashScreen;
    splash->setPixmap(QPixmap(":/dredgingSplash.png"));
    splash->show();
    Qt::Alignment topRight = Qt::AlignRight | Qt::AlignTop;
    splash->showMessage(QObject::tr("Setting up the main window..."), topRight, Qt::white);

    MainWindow w;

    splash->showMessage(QObject::tr("loading modules..."), topRight, Qt::white);
    splash->showMessage(QObject::tr("Establishing Connections..."), topRight, Qt::white);

    w.show();    
    splash->finish(&w);

    return a.exec();
}

EDITS 2 using a class:

#include <QApplication>
#include <QSplashScreen>
#include <QTimer>

class ShowImageTime {
public:
    void slInit();
};

int main(int argc, char *argv[])
{

    QApplication a(argc, argv);

    QSplashScreen *splash = new QSplashScreen;
    splash->setPixmap(QPixmap(":/dredgingSplash.png"));
    splash->show();
    Qt::Alignment topRight = Qt::AlignRight | Qt::AlignTop;
    splash->showMessage(QObject::tr("Setting up the main window..."), topRight, Qt::white);

    MainWindow w;

    QTimer::singleShot(3000, splash, SLOT(close()));// close splash after 4s
    QTimer::singleShot(3000, &w, SLOT(ShowImageTime::slInit(this->show)));// mainwindow reappears after 4s

    splash->showMessage(QObject::tr("loading modules..."), topRight, Qt::white);
    splash->showMessage(QObject::tr("Establishing Connections..."), topRight, Qt::white);

    w.show();    
    splash->finish(&w);

    return a.exec();
}

I tried to play with the QTimer as I thought that could be the potential problem due to priority of loading, but unfortunately if I change QTimer::singleShot(2500, splash, SLOT(close())); with QTimer::singleShot(12500, splash, SLOT(close())); or even higher numbers, there is literally no difference, so I am not sure why that is not an option.

Also I came across this source and I also followed official documentation but that also did not help me to figure out the problem. Also this post suggests that the problem keeps being related to the QTimer but I don't see how since bigger or smaller intervals seems not to count.

What am I missing to keep the QSplashScreen to stay for 2 seconds instead of disappearing (or not even see it) right away? Thanks for pointing to the right direction.


Solution

  • The problem is, that your code is starting the timer and then continues running. So the MainWindow is created, shown and the SplashScreen is deleted/finished. The timer's timout function will trigger after all this happened. That is why it closes so quickly.

    SplashScreens are usually shown, if the application start is very slow, because there is so much going on in the background. In your case, there is basically no load and the code executes super quick.

    You could either use a sleep call for 2sec right after calling splash->show() or put all the code for closing the SplashScreen, showing the Mainwindow in a timer's timout slot and delete the SplashScreen there.