PyQt 指令是如何进行的?

How does a PyQt intruction is proceeding?

作为我的研究结束项目的一部分,我正在开发一个 GUI,它基本上采用输入值并从中进行 运行 计算。当我按下 运行 这些计算的按钮时,我的问题就出现了。我希望在计算期间禁用此按钮,并更改其文本以显示 GUI 正忙。

不幸的是,这些更改仅在计算结束时显示在 GUI 上,而不是之前,即使在代码中 运行s 模拟的函数之前调用它们也是如此。

因此我想知道这些指令是如何进行的,这样我也许可以理解下面发生的事情。

如果需要,这里有一小段代码摘录:

我在推送时调用函数'onButtonClicked'

self.pushButton_simu.clicked.connect(self.onButtonClicked)

然后这个(缩短的)函数调用 'displayGraph' 进行计算并显示结果

def onButtonClicked(self):  
        if (not self.exist and self.simu):
            self.displayGraph()

最后,在这个文件中,我创建了一个文件,我在其中放置了一些值,然后尝试禁用和更改我的按钮的文本(这不会立即起作用)。然后我 运行 使用 'simu.simulation' 进行计算,当它结束时,我的消息框会显示,我的新文本和按钮也会被禁用。然后,当我关闭消息框时,文本立即更改,我的按钮再次变得无法使用。

def displayGraph(self):
        with open("Input_simulation", 'wb') as dataFile: 
                pickle.dump([self.planete.reynolds(), self.planete.reynoldsMagnetique(), self.planete.stuart(), int(self.label_Vnbmode_2.text()), self.spinBox_pasmode.value()], dataFile)

        self.pushButton_simu.setText("Simulation en cours")
        self.pushButton_simu.setEnabled(False)

        mode, wImMax = simu.simulation('Input_simulation')

        infoBox = QtWidgets.QMessageBox()
        infoBox.setIcon(QtWidgets.QMessageBox.Information)
        infoBox.setWindowTitle("Information")
        infoBox.setText("Simulation réussie")
        infoBox.exec_()

        self.pushButton_simu.setEnabled(True)
        self.pushButton_simu.setText("Lancer la simulation")

我试图在 setText 和模拟开始之间添加一个 'time.sleep' 但它根本不起作用所以我真的不明白发生了什么。好像模拟太忙了,没法显示变化。

编辑:感谢 rbaleksandar,我通过使用它解决了我的问题:

QtCore.QCoreApplication.processEvents()

您需要 运行 在单独的线程中进行计算。否则,请确切地体验您的情况 - 您的按钮被阻塞(实际上整个 UI 是),因为密集计算占用了主线程的所有处理时间,UI 也驻留(以及所有与之相关的事情,如绘图、事件处理等)。如果线程正忙于计算你的东西,它就没有 "time" 做任何其他事情了。

通常,这是通过创建一个 QThread 并将另一个对象推送(使用 moveToThread(...))到它来完成的,您将在其中进行实际计算。这个对象被称为工作者,而线程 - 工作者线程。然后,您可以将来自您的工作人员的信号连接到您的按钮或包含它的小部件和 disable/enable 它分别。

替代该解决方案,您可以选择 QRunnable 稍作修改,使其能够实际发送信号(因为 QRunnable 实际上不是 QObject 派生的 class 因此您需要显式继承 QObject 才能使用插槽和信号)。