Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update QMainWindow step by step?

I want to update my QMainWindow step by step. I use sleep method but I cannot see changes. I want to see changes every 3 seconds.

void MainWindow::updateScreen()
{
    ui->pushButton1->show();
    QThread::sleep(3);

    ui->pushButton2->show();
    QThread::sleep(3);

    ui->pushButton3->show();
    QThread::sleep(3);
}

But after 9 seconds, all changes apply immediately.

like image 262
sepfar Avatar asked Aug 03 '18 09:08

sepfar


2 Answers

You never use QThread::sleep() in the main thread because it prevents the GUI from being notified about the events and consequently does not behave correctly, the other questions argue correctly so I will not dedicate myself to it, my answer will be centered in giving you a solution that I think is the most appropriate with the use of QTimeLine:

const QWidgetList buttons{ui->pushButton1, ui->pushButton2, ui->pushButton3};

QTimeLine *timeLine =  new QTimeLine( 3000*buttons.size(), this);
timeLine->setFrameRange(0, buttons.size());
connect(timeLine, &QTimeLine::frameChanged, [buttons](int i){
    buttons[i-1]->show();
});
connect(timeLine, &QTimeLine::finished, timeLine, &QTimeLine::deleteLater);
timeLine->start();

I do not recommend using processEvents() because many beginners abuse it thinking it is the magic solution, for example the @cbuchart solution is incorrect because it solves the immediate problem but not the background, for example try to change the size of the window in those 9 seconds. Can you do it? Well, not since the QThread::sleep() is blocking.

Consider a bad practice to use QThread::sleep() in the GUI thread, if you see it somewhere, mistrust.

like image 137
eyllanesc Avatar answered Sep 21 '22 04:09

eyllanesc


I would suggest you to use QTimer::singleShot static method.

void MainWindow::updateScreen()
{
    QTimer::singleShot(3000, [this](){ui->pushButton1->show();});
    QTimer::singleShot(6000, [this](){ui->pushButton2->show();});
    QTimer::singleShot(9000, [this](){ui->pushButton3->show();});
}
like image 43
Andrii Avatar answered Sep 21 '22 04:09

Andrii