Python PySide和进度栏线程 [英] Python PySide and Progress Bar Threading

查看:111
本文介绍了Python 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_())

我希望进度条位于单独的线程中,因此它不会冻结应用程序,但我似乎找不到解决方法.

I want to have the progress bar in a separate thread, so it doesn't freeze up the application, but I can't seem to find how to do so.

任何人都可以帮忙吗?

推荐答案

我认为您可能会误会.您希望将您正在执行的工作放在单独的线程中,以免冻结应用程序.但是您还希望能够更新进度条.您可以通过使用QThread创建辅助类来实现此目的. QThread能够发出信号,您的UI可以侦听并采取适当的行动.

I think you may be mistaken. You want the work you're doing in a separate thread so it doesn't freeze the application. But you also want to be able to update the progress bar. You can achieve this by creating a worker class using a QThread. QThreads are able emit signals, which your UI can listen for and act appropriately.

首先,让我们创建您的worker类.

First, let's create your worker class.

#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)

现在您有了一个工人阶级,现在是时候使用它了.您将要在Ui_Dialog类中创建一个新函数来处理发出的信号.

So now that you have a worker class, it's time to make use of it. You will want to create a new function in your Ui_Dialog class to handle the emitted signals.

def setProgress(self, progress):
    self.progressBar.setValue(progress)

在那里,您可以删除progress()函数.

While you're there, you can remove your progress() function.

retranslateUi()中,您将需要从以下位置更新按钮事件处理程序

in retranslateUi() you will want to update the push button event handler from

self.pushButton.clicked.connect(self.progress)

self.pushButton.clicked.connect(self.worker.start)

最后,在您的setupUI()函数中,您需要创建一个worker类的实例,并将其信号连接到您的setProgress()函数.

Finally, in your setupUI() function, you will need to create an instance of your worker class and connect it's signal to your setProgress() function.

在此之前:

self.retranslateUi(Dialog)

添加此内容:

self.worker = Worker()
self.worker.updateProgress.connect(self.setProgress)


这是最终代码:


Here is the final code:

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_())


QThreads具有一些内置的信号,这些信号会自动发出.您可以在文档中看到它们,以及有关QThreads的更多信息

这篇关于Python PySide和进度栏线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆