Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何愚弄Windows,使其认为您的应用程序仍然很忙,尽管它';她没有反应_Windows_Qt - Fatal编程技术网

如何愚弄Windows,使其认为您的应用程序仍然很忙,尽管它';她没有反应

如何愚弄Windows,使其认为您的应用程序仍然很忙,尽管它';她没有反应,windows,qt,Windows,Qt,我的应用程序是一个窗口应用程序,它执行某些复杂的数学算法。因为我很久以前就开始使用这个应用程序了,所以它的大部分仍然是单线程的。更准确地说,主线程执行所有复杂的计算逻辑。值得一提的是,在计算过程中,我在屏幕上显示了一些进度 在大多数情况下,数学算法只需要几秒钟,因此在用户开始操作后,会显示沙漏(或Windows 7中的运行圆圈),几秒钟后会显示结果 在某些情况下,该算法可能需要几分钟。在这段时间里,我显示沙漏,当算法繁忙时,我在窗口中显示进度。但是,如果用户在应用程序忙碌了一段时间后单击该应用程

我的应用程序是一个窗口应用程序,它执行某些复杂的数学算法。因为我很久以前就开始使用这个应用程序了,所以它的大部分仍然是单线程的。更准确地说,主线程执行所有复杂的计算逻辑。值得一提的是,在计算过程中,我在屏幕上显示了一些进度

在大多数情况下,数学算法只需要几秒钟,因此在用户开始操作后,会显示沙漏(或Windows 7中的运行圆圈),几秒钟后会显示结果

在某些情况下,该算法可能需要几分钟。在这段时间里,我显示沙漏,当算法繁忙时,我在窗口中显示进度。但是,如果用户在应用程序忙碌了一段时间后单击该应用程序,则窗口会变得“更白”(就像在窗口上放置了一块不完全透明的塑料),窗口不再更新,并且Windows会报告“应用程序没有响应”

我使用Qt和Qt函数QWidget::repaint在算法繁忙时强制重新绘制。重新油漆工作了一段时间,但如上所述,Windows似乎阻止了一段时间后这一点

告诉Windows您的应用程序仍处于繁忙状态以便窗口不断更新的正确方法是什么?如果我输入一个显式消息循环,用户可能会触发应用程序中我不想要的其他操作

  • 打电话给PeekMessage够了吗
  • 调用GetMessage就足够了吗
  • 或者我应该打电话给DispatchMessage?我如何阻止用户启动另一个操作(实际上,阻止所有用户输入)
  • 我应该在每次更新窗口时调用其中一条消息,还是可以限制自己每隔几秒钟调用一次(10秒?、30秒?…)
请注意,将计算逻辑移动到单独的线程当前不是一个选项


我在Windows 7上使用Visual Studio 2010,并与Qt 4.7结合使用。

您只需不时调用
QApplication::processEvents()
,比如每2秒或3秒左右。这将触发重新绘制事件并刷新进度条和其他元素。

类似的问题和大量信息如下:


然而,正如您可能已经知道的,这是一个相当大的攻击,最好尝试将代码移动到另一个线程。为什么这不是一个选项?

您应该将GUI与应用程序逻辑分开。所有其他解决方案都是黑客。使用
Qt
可以轻松地将计算逻辑移动到单独的线程

我假设有一个函数(我们称之为
execute()
)在被调用时执行所有这些耗时的数学运算。一个选项是使用在单独的线程中调用此函数,而不使用低级线程处理

您需要的是功能:

QtConcurrent::run()函数在单独的线程中运行函数。 函数的返回值通过QFuture提供 API

与其简单地调用将阻塞用户界面的
execute()
,您可以执行以下操作(让
A
成为定义
execute()
的类):

QFuture future=QtConcurrent::run(this,&A::execute);

您可以使用,以便在函数完成时获得通知

DisableProcessWindowGhosting函数(请参阅)告诉Windows,如果应用程序没有响应,它不得显示“重影窗口”

我的同事用它做了一些实验,并注意到以下几点:

  • 显示进度的动画继续进行得很好(这实际上是我想要实现的)
  • 用户仍然可以最小化、移动。。。窗户(很棒)
  • 缺点:如果应用程序真的挂起了,用户必须使用任务管理器来终止它

因此,这就解决了我的问题。

Re“用户可能会触发应用程序中我不想要的其他操作。”因此,请禁用这些控件。感谢链接。将其移动到单独的线程目前不是一个选项,因为在通过UI代码调用的计算算法中仍然有很多旧代码(它甚至可能显示一个对话框:-)。很有趣。我来看看。
QFuture<void> future = QtConcurrent::run(this, &A::execute);