我的应用程序是一个窗口应用程序,执行某些复杂的数学算法.因为我很久以前就开始使用该应用程序,所以大多数仍然是单线程的.更确切地说,主线程执行所有复杂的计算逻辑.值得一提的是,在计算过程中,我在屏幕上显示了一些进展.
在大多数情况下,数学算法只需要几秒钟,因此在用户启动操作后,会显示沙漏(或Windows 7中的运行圆圈),几秒钟后会显示结果.
在某些情况下,算法可能需要几分钟.在此期间,我显示了沙漏,当算法繁忙时,我会在窗口中显示进度.但是,如果用户在忙碌一段时间后点击应用程序,则窗口变得"更白"(好像在窗口上放置了一块非完全透明的塑料),窗口不再更新,Windows报告"应用程序没有响应".
我使用Qt,我使用Qt函数QWidget :: repaint强制重绘,而我的算法很忙.重绘工作了一段时间,但如上所述,Windows似乎在一段时间后阻止了这一点.
告诉Windows您的应用程序是否仍然繁忙以便窗口不断更新的正确方法是什么?如果我进入显式消息循环,用户可能会触发应用程序中我不想要的其他操作.
请注意,将计算逻辑移动到单独的线程当前不是一个选项.
我在Windows 7上使用Visual Studio 2010,与Qt 4.7结合使用.
您应该将GUI与应用程序逻辑分开.所有其他解决方案都是黑客.Qt使用较小的工作可以轻松地将计算逻辑移动到单独的线程.
我假设有一个函数(让我们调用它execute()),当被调用时执行所有这些耗时的数学运算.一种选择是使用Qt Concurrent API在单独的线程中调用此函数,而不使用低级线程处理.
你需要的是QtConcurrent::run功能:
QtConcurrent :: run()函数在一个单独的线程中运行一个函数.该函数的返回值可通过QFuture API获得.
而不是简单地调用execute()哪个将阻止您的用户界面,您可以执行以下操作(让我们定义A的类execute()):
QFuture<void> future = QtConcurrent::run(this, &A::execute);
Run Code Online (Sandbox Code Playgroud)
您可以使用QFutrureWatcher以获得有关函数何时完成的通知.
DisableProcessWindowGhosting 函数(请参阅http://msdn.microsoft.com/en-us/library/ms648415(v=vs.85).aspx)告诉 Windows,如果应用程序没有响应,它不得显示“幽灵窗口” 。
我的同事用它做了一些实验并注意到以下几点:
所以,这解决了我的问题。