Ben*_*nny 17 python qt multithreading pyside
我有这个代码:
from PySide import QtCore, QtGui
import time
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 133)
self.progressBar = QtGui.QProgressBar(Dialog)
self.progressBar.setGeometry(QtCore.QRect(20, 10, 361, 23))
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.pushButton = QtGui.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(20, 40, 361, 61))
self.pushButton.setObjectName("pushButton")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("Dialog", "PushButton", None, QtGui.QApplication.UnicodeUTF8))
self.progressBar.setValue(0)
self.pushButton.clicked.connect(self.progress)
def progress(self):
self.progressBar.minimum = 1
self.progressBar.maximum = 100
for i in range(1, 101):
self.progressBar.setValue(i)
time.sleep(0.1)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Dialog = QtGui.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)
我希望在一个单独的线程中有进度条,所以它不会冻结应用程序,但我似乎无法找到如何这样做.
有人可以帮忙吗?
smo*_*ont 31
我想你可能弄错了.您希望在单独的线程中执行的工作因此不会冻结应用程序.但您也希望能够更新进度条.您可以通过使用a创建工作类来实现此目的QThread.QThreads能够发出信号,您的UI可以监听并采取适当的行动.
首先,让我们创建你的工人类.
#Inherit from QThread
class Worker(QtCore.QThread):
#This is the signal that will be emitted during the processing.
#By including int as an argument, it lets the signal know to expect
#an integer argument when emitting.
updateProgress = QtCore.Signal(int)
#You can do any extra things in this init you need, but for this example
#nothing else needs to be done expect call the super's init
def __init__(self):
QtCore.QThread.__init__(self)
#A QThread is run by calling it's start() function, which calls this run()
#function in it's own "thread".
def run(self):
#Notice this is the same thing you were doing in your progress() function
for i in range(1, 101):
#Emit the signal so it can be received on the UI side.
self.updateProgress.emit(i)
time.sleep(0.1)
Run Code Online (Sandbox Code Playgroud)
所以现在你有了一个工人阶级,是时候利用它了.您需要在Ui_Dialog类中创建一个新函数来处理发出的信号.
def setProgress(self, progress):
self.progressBar.setValue(progress)
Run Code Online (Sandbox Code Playgroud)
当你在那里时,你可以删除你的progress()功能.
在retranslateUi()你想要更新按钮事件处理程序
self.pushButton.clicked.connect(self.progress)
Run Code Online (Sandbox Code Playgroud)
至
self.pushButton.clicked.connect(self.worker.start)
Run Code Online (Sandbox Code Playgroud)
最后,在您的setupUI()函数中,您需要创建worker类的实例并将其信号连接到您的setProgress()函数.
在这之前:
self.retranslateUi(Dialog)
Run Code Online (Sandbox Code Playgroud)
添加这个:
self.worker = Worker()
self.worker.updateProgress.connect(self.setProgress)
Run Code Online (Sandbox Code Playgroud)
这是最终的代码:
from PySide import QtCore, QtGui
import time
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 133)
self.progressBar = QtGui.QProgressBar(Dialog)
self.progressBar.setGeometry(QtCore.QRect(20, 10, 361, 23))
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.pushButton = QtGui.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(20, 40, 361, 61))
self.pushButton.setObjectName("pushButton")
self.worker = Worker()
self.worker.updateProgress.connect(self.setProgress)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
self.progressBar.minimum = 1
self.progressBar.maximum = 100
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("Dialog", "PushButton", None, QtGui.QApplication.UnicodeUTF8))
self.progressBar.setValue(0)
self.pushButton.clicked.connect(self.worker.start)
def setProgress(self, progress):
self.progressBar.setValue(progress)
#Inherit from QThread
class Worker(QtCore.QThread):
#This is the signal that will be emitted during the processing.
#By including int as an argument, it lets the signal know to expect
#an integer argument when emitting.
updateProgress = QtCore.Signal(int)
#You can do any extra things in this init you need, but for this example
#nothing else needs to be done expect call the super's init
def __init__(self):
QtCore.QThread.__init__(self)
#A QThread is run by calling it's start() function, which calls this run()
#function in it's own "thread".
def run(self):
#Notice this is the same thing you were doing in your progress() function
for i in range(1, 101):
#Emit the signal so it can be received on the UI side.
self.updateProgress.emit(i)
time.sleep(0.1)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Dialog = QtGui.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)
QThreads有一些自动发出的内置信号.您可以在文档中看到它们以及有关QThreads的更多信息
ekh*_*oro 13
认为你总是需要使用多线程来做这样的事情是错误的.
如果您可以将长时间运行的任务分解为一系列小步骤,那么您需要做的就是确保经常处理任何待处理事件,以便GUI保持响应.这可以安全地从完成内主界面线程使用processEvents,就像这样:
for i in range(1, 101):
self.progressBar.setValue(i)
QtGui.qApp.processEvents()
time.sleep(0.1)
Run Code Online (Sandbox Code Playgroud)
鉴于它的简单性,在选择更多重量级解决方案(如多线程或多处理)之前,至少考虑这种技术总是值得的.
| 归档时间: |
|
| 查看次数: |
14330 次 |
| 最近记录: |