QCoreApplication.processEvents 行为

Posted

技术标签:

【中文标题】QCoreApplication.processEvents 行为【英文标题】:QCoreApplication.processEvents behavior 【发布时间】:2017-06-06 17:19:51 【问题描述】:

我正在做时间非常重要的工作,并且对 processEvents() 的行为有疑问。当我调用 processEvents() 时,它是否在单独的线程/进程上运行,以便在执行更多代码时它可能仍在运行?

如果没有,我的代码是否有可能在 processEvents() 之后但在我的监视器上的所有像素更新到最新场景之前继续执行(可能是因为操作系统处理像素绘制)?下面是伪代码

app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.drawScene()
app.processEvents() #Force window to update to scene
print("Hi!") #Is there any chance of this being called before my screen's pixels are all set to the newest scene?

如果 processEvents() 之后的代码在屏幕像素全部更新之前运行,有没有办法保证屏幕在继续之前更新?

【问题讨论】:

【参考方案1】:

QCoreApplication::processEvents() 在您调用它的同一线程中运行,它不使用单独的线程。它将处理当前在事件队列中排队的所有事件。如果队列中有QEvent::Paint 类型的事件,它将触发窗口的重绘。您的drawScene() 可能会通过直接或间接调用QWidget::update() 将绘制事件放入事件队列中。

是的,对processEvents() 的调用将完成挂起的重绘,并且仅在重绘事件处理完毕后返回。

FWIW,QProgressDialog::setValue() 内部调用 processEvents() 以确保更新进度条,所以这也必须在那里工作。

我能想到导致像素不显示的唯一原因是所谓的平台插件中的平台特定代码在重新绘制时执行了异步操作。需要仔细检查您正在使用的操作系统的平台插件代码以绝对确定。

这实际上似乎是 X11 上的情况,它是异步的。检查docs for QTest::qWaitForWindowExposed - 它在内部循环调用processEvents(),直到QWindow::isExposed() 返回true。因此,至少对于最初显示窗口,您需要在循环中运行processEvents() 以确保实际显示窗口。我不知道是否需要重新粉刷。 详情请见the section "Visibility and Windowing System Exposure" in the docs of QWindow。

【讨论】:

循环运行processEvents() 是什么意思?据我所知,它没有返回任何东西 我认为代码解释得比我能解释的更好——看看code.woboq.org/qt5/qtbase/src/testlib/…的qWaitForWindowExposed代码

以上是关于QCoreApplication.processEvents 行为的主要内容,如果未能解决你的问题,请参考以下文章