我希望按下按钮时出现一个 Qlabel,以告知工作流程。但是在执行 start_calc 后调用了 setenabled(True)。如何修复它?
from PyQt5 import QtWidgets
import time
class MyWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.mainWidgets = QtWidgets.QWidget()
self.layout = QtWidgets.QHBoxLayout()
self.label = QtWidgets.QLabel()
self.label.setText('loading...')
self.button = QtWidgets.QPushButton()
self.button.setText('start')
self.layout.addWidget(self.button)
self.layout.addWidget(self.label)
self.mainWidgets.setLayout(self.layout)
self.setCentralWidget(self.mainWidgets)
self.label.setEnabled(False)
self.button.clicked.connect(self.start_calc)
def start_calc(self):
self.label.setEnabled(True)
time.sleep(3) #Simulating some time-consuming calculation
self.label.setEnabled(False)
app = QtWidgets.QApplication([])
application = MyWindow()
application.show()
app.exec()
我预计按下按钮后会出现一条消息,在 time.sleep(3) 之后它会消失
在 Qt 中,主线程负责管理 GUI 并对其进行更新,因此它永远不应该被阻塞。
当您按下按钮时,主线程将停止管理 GUI,然后开始执行插槽中的代码,并且只有在执行完成后才会更改 GUI。因此,它看到您想要启用标签,然后它会休眠 3 秒,因为
time.sleep(3)
导致应用程序延迟 3 秒,因为记住没有 GUI 管理发生,然后它再次看到您想要禁用该标签,但由于它最终已经被禁用,它不会对 GUI 进行任何更改。
如果您想在后台工作并在完成后进行 GUI 更改,请创建一个插槽,该插槽将在主线程上执行 GUI 更改并将该插槽连接到信号。启动一个
QThread
来执行生成更改所需数据所需的工作,完成后将信号发送到包含更改所需数据的插槽。
但在您的情况下,
QTimer
就足够了,因为不需要新的数据/处理来更改 GUI。
from PyQt5.QtCore import QTimer
# Your other stuff
def start_calc(self):
self.label.setEnabled(True)
QTimer.singleShot(3000, lambda: self.label.setEnabled(False))