简体   繁体   English

QT / QML主GUI窗口的加载会减慢启动画面的渲染

[英]Loading of Main QT/QML GUI Window Slows Down Rendering of Splash Screen

I am using the C++/Qt/QML stack to develop a GUI application. 我正在使用C ++ / Qt / QML堆栈来开发GUI应用程序。

On application startup, I have a splash screen that displays while the main window is loading. 在应用程序启动时,我有一个初始屏幕,在加载主窗口时显示。 I want the splash screen to provides updates (let's say, every 200ms) to the loading status of the main window. 我希望启动屏幕提供对主窗口的加载状态的更新(比方说,每200毫秒一次)。

However, the loading of the main window causes the 200ms "this is the update" rendering of the splash screen to get interrupted. 但是,主窗口的加载会导致初始屏幕的200ms“这是更新”渲​​染中断。 The code which slows down the splash screen is: 减慢启动屏幕速度的代码是:

this->engine = new QQmlApplicationEngine;
engine->load(QUrl("qrc:/mainWindow.qml")); // This line causes splash screen rendering to lag!

So I thought, ok, I'll put the splash screen process into a higher priority thread, so that it's render/update process won't get "as" interrupted. 所以我想,好的,我将启动屏幕进程放入一个更高优先级的线程中,以便其渲染/更新进程不会被“ as”打断。

But...I have found out that all QQmlApplicationEngine objects must be created/used in the same thread, namely the one which QApplication (a singleton) is created in. 但是...我发现所有QQmlApplicationEngine对象必须在同一线程中创建/使用,即在其中创建QApplication (单例)的那个线程。

I get that if I had heavily computational operations I could put them into a worker thread, but this scenario is a little different, because the thing that is causing the lag is a GUI method call, which Qt doesn't allow to be in a separate thread. 我得到的是,如果我有大量的计算操作,可以将它们放入工作线程中,但是这种情况有些不同,因为导致延迟的原因是GUI方法调用,而Qt不允许在其中进行操作。单独的线程。

How can I achieve what I want with this limitation? 如何通过此限制实现我想要的?

Just an idea (after reading the source code and docs), not a tested solution: 只是一个想法(阅读源代码和文档之后),而不是经过测试的解决方案:

QQmlApplicationEngine combines a QQmlEngine and QQmlComponent to provide a convenient way to load a single QML file. QQmlApplicationEngine结合了QQmlEngine和QQmlComponent,以提供一种方便的方式来加载单个QML文件。

QQmlComponent provides progressChanged() signal which you can use to update your splash screen. QQmlComponent提供了progressChanged()信号,可用于更新初始屏幕。

I hope you can achieve what you want if you can separate QQmlApplicationEngine into QQmlComponent to load a QML first (use the progressChanged() or a timer to update the splash screen) and then chuck it into QQmlEngine (mimicking the way of QQmlApplicationEngine C:\\Qt\\5.4\\Src\\qtdeclarative\\src\\qml\\qml\\qqmlapplicationengine.cpp ). 我希望您可以实现以下目标,如果您可以将QQmlApplicationEngine分离到QQmlComponent中以首先加载QML(使用progressChanged()或计时器来更新初始屏幕),然后将其卡入QQmlEngine(模仿QQmlApplicationEngine C的方式:\\ Qt \\ 5.4 \\ Src \\ qtdeclarative \\ src \\ qml \\ qml \\ qqmlapplicationengine.cpp)。

PS When you do all this, your main loop should be running already in order to make signals work. PS完成所有这些操作后,主循环应该已经在运行,以使信号正常工作。

Instead of using QQmlApplicationEngine 's engine, you can use your own. 您可以使用自己的引擎,而不是使用QQmlApplicationEngine的引擎。 You can certainly load everything up in another thread, then ship the whole engine back to the main thread and start rendering there. 您当然可以将所有内容加载到另一个线程中,然后将整个引擎发回主线程并在那里开始渲染。 Just make sure that none of the windows are visible, if you have Window objects there. 如果您有Window对象,只需确保所有窗口都不可见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM