我正在进行计时非常重要的工作,并且对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()之后的代码确实在屏幕像素全部更新之前运行,是否有办法保证在继续之前更新屏幕?

最佳答案

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

10-06 08:41