Qt:慢启动时显示窗口内容

时间:2016-06-09 17:59:32

标签: c++ qt redraw

感觉此问题已被问过一百次(例如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()返回后立即绘制(这似乎对我来说是合乎逻辑的,因为事件循环还没有开始..)

1 个答案:

答案 0 :(得分:1)

  

注意:这个建议并没有解决问题;它离开这里是为了完整。

您可以将启动分成main()中的较小步骤:

  1. 创建QApplication实例。
  2. 实例化主窗口(我在这里调用变量mainWindow)。您可以从代码示例的构造函数中安全地删除initializeUI();之后的所有重绘工作内容。
  3. 调用mainWindow.show()强制显示主窗口,然后调用QApplication::processEvents()以强制执行正在处理的绘制事件。
  4. 执行应用程序的所有其他初始化操作。
  5. 通过调用QApplication::exec()
  6. 照常启动事件循环

    请注意,对于复杂的应用程序/主窗口实现,以正确的顺序执行所有操作可能会非常繁琐;一个QSplashScreen肯定是不那么乏味的解决方案。