我正在开发一个应用程序,我需要使用 QProgressBar 来让用户了解进度。但是,我不想按步骤更新进度条,而是想使用 setMaximum(0) 在进度条上显示“忙碌”指示器并更新 QLabel 以显示当前阶段。我这样做是为了让一切变得简单。
这是一个模拟 UI,用于简化说明。
这是相应的代码:
class TestWindow(QMainWindow):
def __init__(self):
super().__init__()
relpath = 'ui/test.ui'
uifile = join(dirname(sys.argv[0]), relpath)
uic.loadUi(uifile, self)
self.pushButton.clicked.connect(self.start_updating)
def start_updating(self):
self.progressBar.setMaximum(0)
self.label.setText("Func 1")
sleep(3) # in real app do something here
self.label.setText("Func 2")
sleep(3) # in real app do something else here
self.label.setText("Func 3")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = TestWindow()
window.show()
sys.exit(app.exec_())
如果我运行此命令,则仅显示 QLabel 的最后一个状态(“Func 3”),并且直到最后一次更新标签文本之前,进度条上不会显示“忙碌”模式。谁能帮助我理解为什么这不起作用以及是否有更好的方法来定期更新标签?
最佳答案
您不应该在 GUI 线程中执行繁重的任务,因为它们会阻止事件循环,从而阻止 GUI 更新,例如在您的情况下,标签未更新。相反,您必须在另一个线程中执行该任务并通过信号发送更新 GUI 的信息:
import os
import sys
import time
from PyQt5 import QtCore, QtGui, QtWidgets, uic
class Worker(QtCore.QObject):
textChanged = QtCore.pyqtSignal(str)
started = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
@QtCore.pyqtSlot()
def run_task(self):
self.started.emit()
self.textChanged.emit("Func 1")
time.sleep(3) # in real app do something here
self.textChanged.emit("Func 2")
time.sleep(3) # in real app do something else here
self.textChanged.emit("Func 3")
self.finished.emit()
class TestWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
relpath = "ui/test.ui"
current_dir = os.path.dirname(os.path.realpath(__file__))
uifile = os.path.join(current_dir, relpath)
uic.loadUi(uifile, self)
thread = QtCore.QThread(self)
thread.start()
self.m_worker = Worker()
self.m_worker.moveToThread(thread)
self.m_worker.started.connect(self.onStarted)
self.m_worker.finished.connect(self.onFinished)
self.m_worker.textChanged.connect(self.update_label)
self.pushButton.clicked.connect(self.m_worker.run_task)
self.progressBar.setValue(0)
@QtCore.pyqtSlot()
def onStarted(self):
self.progressBar.setMaximum(0)
self.pushButton.setEnabled(False)
@QtCore.pyqtSlot()
def onFinished(self):
self.progressBar.setMaximum(1)
self.progressBar.setValue(1)
self.pushButton.setEnabled(True)
@QtCore.pyqtSlot(str)
def update_label(self, text):
self.label.setText(text)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = TestWindow()
window.show()
sys.exit(app.exec_())
关于python - 定期更新带有标签的 ProgressBar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57162569/