在计算期间在 PySide(或 PyQt)中使用 QProgressBar 实现 QThread
Posted
技术标签:
【中文标题】在计算期间在 PySide(或 PyQt)中使用 QProgressBar 实现 QThread【英文标题】:Implement QThread with QProgressBar in PySide (or PyQt) during calculation 【发布时间】:2019-11-28 05:40:29 【问题描述】:我想知道如何实现QProgressBar,它显示了主线程中的计算进度。
请参考以下代码。
import sys
from PySide2.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QProgressBar
from PySide2.QtCore import QThread
class BarThread(QThread):
# Progress Bar UI Definition
def __init__(self):
QThread.__init__(self)
self.window = QWidget()
self.pgsb = QProgressBar()
self.lay = QVBoxLayout()
self.lay.addWidget(self.pgsb)
self.window.setLayout(self.lay)
self.isRun = False
# Thread Function Definition
def run(self):
self.window.show()
while self.isRun:
self.pgsb.setValue(self.percent)
print(self.percent)
if self.percent == 100:
self.isRun = False
class Tool(QWidget):
# Main UI Definition
def __init__(self):
windowWidth = 300
windowHeight = 300
QWidget.__init__(self)
self.setWindowTitle("Example")
self.resize(windowWidth, windowHeight)
self.bt = QPushButton('Numbering')
self.layout = QVBoxLayout()
self.layout.addWidget(self.bt)
self.setLayout(self.layout)
# Main Function Link Definition
self.bt.clicked.connect(self.numbering)
# Main Function Definition
def numbering(self):
bth = BarThread()
bth.start()
bth.isRun = True
for x in range(0,100000):
bth.percent = x/1000
print(x)
if __name__ == "__main__":
app = QApplication(sys.argv)
widget = Tool()
widget.show()
sys.exit(app.exec_())
您可以直接复制并粘贴到您的 python IDE 中。
(它需要 PySide2。可以在提示符中使用“pip install pyside2”进行安装)。
此代码执行简单编号,但是,这不显示编号进度。
我该如何解决这个问题?提前谢谢你。
附:我正在使用带有 PyCharm 的 Windows 10。
【问题讨论】:
【参考方案1】:您至少有以下错误:
您不能从另一个线程修改 GUI,在您的情况下,run 方法在另一个线程中执行,但您尝试修改 QProgressBar 的值,除了显示一个不允许的小部件。如果您想使用辅助线程执行中提供的信息修改 GUI,您必须通过信号来完成,因为它们是线程安全的
for 循环是阻塞任务,所以它必须在另一个线程中执行。
综合以上情况,解决办法是:
import sys
from PySide2.QtWidgets import (
QApplication,
QWidget,
QPushButton,
QVBoxLayout,
QProgressBar,
)
from PySide2.QtCore import QThread, Signal
class ProgressWidget(QWidget):
def __init__(self, parent=None):
super(ProgressWidget, self).__init__(parent)
self.pgsb = QProgressBar()
lay = QVBoxLayout(self)
lay.addWidget(self.pgsb)
class BarThread(QThread):
progressChanged = Signal(int)
def run(self):
percent = 0
for x in range(0, 100000):
percent = x / 100
self.progressChanged.emit(percent)
class Tool(QWidget):
"""Main UI Definition"""
def __init__(self, parent=None):
super(Tool, self).__init__(parent)
self.setWindowTitle("Example")
self.resize(300, 300)
self.bt = QPushButton("Numbering")
layout = QVBoxLayout(self)
layout.addWidget(self.bt)
# Main Function Link Definition
self.bt.clicked.connect(self.numbering)
self.bar_thread = BarThread(self)
self.progress_widget = ProgressWidget()
self.bar_thread.progressChanged.connect(self.progress_widget.pgsb.setValue)
# Main Function Definition
def numbering(self):
self.bar_thread.start()
self.progress_widget.show()
def closeEvent(self, event):
super(Tool, self).closeEvent(event)
self.bar_thread.quit()
self.bar_thread.wait()
if __name__ == "__main__":
app = QApplication(sys.argv)
widget = Tool()
widget.show()
sys.exit(app.exec_())
【讨论】:
以上是关于在计算期间在 PySide(或 PyQt)中使用 QProgressBar 实现 QThread的主要内容,如果未能解决你的问题,请参考以下文章
使用 PyQt4 或 PySide 捕获屏幕,除了特定的小部件?
Python/pyside,pyqt(pyside,pyqt optional): 控制文本选择的函数
如何在 Qt/PyQt/PySide 中找到当前的 QLocale?