【发布时间】:2016-10-10 12:40:59
【问题描述】:
感觉这个问题之前已经被问过一百次了(例如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() 方法放入 main() 函数中,就像 Murphy 建议的那样:
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() 返回后立即绘制(这对我来说似乎是合乎逻辑的,因为事件循环尚未启动然而..)
【问题讨论】:
-
我建议在显示主窗口之前先进行一些启动,这样可以在加载时给您一些时间,这适合您吗?
-
嗯 - 这可能是一种选择,我会更符合用户的期望。目前感觉有点像放弃:)。我真的很想知道在显示 UI 后我应该怎么做才能调用这个函数。
-
在初始化完成之前,程序无论如何都不能使用。,那么你为什么要显示一个几秒钟不可用的窗口呢?我认为在这种情况下启动画面更方便。 . .
-
你是对的——这就是我将这样做的方式,这就是为什么我赞成你的评论。我只是想知道如何说服 Qt 只绘制一个窗口并运行一个方法之后。