感觉此问题已被问过一百次(例如here),但我还没有找到可行的解决方案..
我有一个Qt5程序(Linux)需要一些时间(约2秒)进行初始化。我不想生成一个线程(由于几个原因),并且在初始化完成之前,该程序无论如何都不可用。
目前程序启动并显示黑色窗口,直到初始化完成。
我希望尽快绘制窗口内容,然后排队一个方法,在绘制主窗口后立即执行其余操作。
这就是我的尝试:
class my_window : public QMainWindow {
Q_OBJECT
explicit my_window(QWidget *parent = 0) : QMainWindow(parent) {
initializeUI();
/// UI is ready and should be drawn. initializeRest() should
/// be queued
/// tried to repaint() or update() the MainWindow and to 'force'
/// processing outstanding events - with no effect
update();
repaint();
QApplication::processEvents();
/// don't call - just queue
QMetaObject::invokeMethod(this, "initializeRest", Qt::QueuedConnection);
}
void initializeRest() {
// do stuff which takes a while
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
但主窗口在执行initializeRest()
之前一直保持黑色。
如何在构建窗口后立即告诉Qt执行initializeRest()
?
我可以考虑启动一个计时器(糟糕,引入额外的延迟)或一个对某种“WindowDrawn”事件做出反应的事件处理程序(糟糕,复杂)。
这样做的Qt方式是什么?
更新:
我还尝试将initializeRest()
方法放入Murphy建议的main()
函数中:
my_window::my_window(QWidget *parent = 0) : QMainWindow(parent) {
initializeUI();
}
int main(int a_argsc, char *a_argsv[]) {
QApplication l_application(a_argsc, a_argsv);
my_window mainWindow;
mainWindow.show();
QApplication::processEvents();
mainWindow.initializeRest();
return l_application.exec();
}
结果相同:在initializeRest()
内等待几秒钟会显示最初的黑色主窗口,并在initializeRest()
返回后立即绘制(这似乎对我来说是合乎逻辑的,因为事件循环还没有开始..)
答案 0 :(得分:1)
注意:这个建议并没有解决问题;它离开这里是为了完整。
您可以将启动分成main()
中的较小步骤:
QApplication
实例。mainWindow
)。您可以从代码示例的构造函数中安全地删除initializeUI();
之后的所有重绘工作内容。mainWindow.show()
强制显示主窗口,然后调用QApplication::processEvents()
以强制执行正在处理的绘制事件。QApplication::exec()
。请注意,对于复杂的应用程序/主窗口实现,以正确的顺序执行所有操作可能会非常繁琐;一个QSplashScreen
肯定是不那么乏味的解决方案。