我正在使用第三方库,需要60-90秒才能动态加载多个库。这是一个不幸的设计选择,但我无法改变构建代码的人。
我正在尝试使用QSplashScreen至少告诉用户在我在后台进行一次性加载时等待。问题是启动画面不是绘画。当库加载时,我可以看到一个非绘画空间的窗口。之后我可以在关闭之前看到启动画面。
我查看了类似的问题(例如Qt Splash Screen not showing)但似乎没有解决我的问题。我试过加载一个空的QPixmap并给它一个纯色。这也没有出现。
QApplication a(argc, argv);
QPixmap pxl("icon.bmp");
QSplashScreen qss(pxl);
qss.show();
qss.showMessage(QString::fromStdString("Please wait... Loading"));
a.processEvents();
MainWindow w;
//thread is blocked
w.preLoad();//this is where the lengthy process takes place
w.show();
qss.finish(&w);
在开始加载过程之前,我想确保至少涂一次。
------------------------ EDIT ---------------------- ---------
让我重申,对preLoad的调用是阻塞线程。这不是一个选择。我为该过程尝试了一个单独的线程。我已尝试使用单独的线程用于启动屏幕(打开它然后完成另一个线程完成)。我尝试在两个线程之间使用信号量来实现这一点,虽然一切正常(包括启动屏幕),但加载需要200-800秒。这根本不可接受。因此,我想从这个角度看看它是否存在。
-------------------------最终解决方案-------------------- ------------
感谢下面的评论,我意识到Qt有自己的线程功能。我看到的所有问题似乎都是由std :: thread和Qt自己实现的相互作用引起的。
我有一个可行的部分解决方案。它并不像它可能那样整洁,但我想将它包含在问题主题中。
//in the main method code described above
MainWindow w;
w.preLoad();
while(w.IsLoading())
{
//waiting on semaphore signaling loading is complete
//this part could probably be done better with QThread
//and signals, but it is a quick fix for now
std::this_thread::sleepfor(std::chrono::milliseconds(500));
a.processEvents();
}
w.show();
qss.finish(&w);
//In the MainWindow class
void MainWindow::preLoad()
{
loading=true;//semaphore to stall main thread
QFuture<void> future = QtConcurrent::run(this, &MainWindow::LongMethod);
}
void MainWindow::LongMethod()
{
thirdPartyLibrary.impossibleCall();
loading=false;//this handles my semaphore
}
答案 0 :(得分:2)
每个GUI都在无限循环中执行,因此Qt也使用它,但是阻塞任务会生成循环未正确执行,显示出与您观察到的行为不一致的行为。
如果想要执行阻塞任务,建议在另一个线程中执行它Qt提供了几种可能性:
我建议您使用以下link为您的案例选择正确的选项。
如果要使用另一个线程中生成的信息更新GUI视图,建议使用信号和插槽,或使用QtConcurrent。
如上所述,每个程序在启动时都有一个线程。这个 线程被称为&#34;主线程&#34; (也称为&#34; GUI线程&#34; in Qt应用程序)。 Qt GUI必须在此线程中运行。所有小部件和 几个相关的课程,例如QPixmap,不在中学工作 线程。辅助线程通常被称为&#34;工作者 螺纹&#34;因为它用于从主要卸载处理工作 线程。
另一种方法是强制GUI更新,我们可以使用qApp->processEvents()。
参考文献: