如何逐步更新QMainWindow

How to update QMainWindow step by step?

本文关键字:QMainWindow 更新 何逐步      更新时间:2023-10-16

我想逐步更新我的QMainWindow。我使用睡眠法,但看不到变化。我希望每3秒钟看到一次变化。

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

但9秒后,所有更改都会立即生效。

您从不在主线程中使用QThread::sleep(),因为它会阻止GUI收到有关事件的通知,从而导致其行为不正确,其他问题争论正确,所以我不会专门讨论它,我的答案将集中在为您提供一个我认为最适合使用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();

我不建议使用processEvents(),因为许多初学者滥用它,认为它是神奇的解决方案,例如@cbuchart解决方案不正确,因为它解决了眼前的问题,但没有解决背景问题,例如,尝试在这9秒内更改窗口的大小。你能做到吗?好吧,不是因为QThread::sleep((正在阻塞。

考虑一下在GUI线程中使用QThread::sleep()坏做法,如果您在某个地方看到它,则表示不信任。

我建议您使用QTimer::singleShot静态方法。

void MainWindow::updateScreen()
{
QTimer::singleShot(3000, [this](){ui->pushButton1->show();});
QTimer::singleShot(6000, [this](){ui->pushButton2->show();});
QTimer::singleShot(9000, [this](){ui->pushButton3->show();});
}

在实际绘制窗口之前,应用的更改不会变为可见。通过在主UI线程上休眠,可以防止系统进行任何绘图,因此在9秒后再次离开更新功能之前,您无法看到更新的发生。

相反,你想做的是让一个不阻塞主UI的单独的线程每三秒发出一次信号,导致各个按钮出现。请确保将这些信号放在QueuedConnection上,以避免小部件出现竞争条件。

或者,如果你不想浪费线程,你也可以有一个连续的更新事件,检查自当前更新周期开始以来已经过去了多少时间,并只有在经过足够的时间后才显示相应的按钮。QTimer类提供了一种方便的方法。只要确保你不会通过执行繁重的计算或睡在同一个线程上来阻止事件循环,否则你将无法再次看到更新。