QCoreApplication.processEvents行为

时间:2017-06-06 17:19:51

标签: python python-3.x qt pyqt pyqt5

我正在做时机非常重要的工作,并且对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 个答案:

答案 0 :(得分:2)

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