Python 如果在多线程情况下打开新的qprogressbar,qprogressbar将停止更新

Python 如果在多线程情况下打开新的qprogressbar,qprogressbar将停止更新,python,multithreading,pyqt,Python,Multithreading,Pyqt,我想更新某个事件进度条上的进度。有多个事件/线程,因此进度条与每个事件/线程关联。但当新线程启动时,前一个线程停止更新进度条。这不应该发生。可以使用以下方法: import sys from PyQt4 import QtGui, QtCore try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_dialog_progress(obj

我想更新某个事件进度条上的进度。有多个事件/线程,因此进度条与每个事件/线程关联。但当新线程启动时,前一个线程停止更新进度条。这不应该发生。可以使用以下方法:

import sys
from PyQt4 import QtGui, QtCore

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s


class Ui_dialog_progress(object):
    def setupUi(self, dialog_progress):
        dialog_progress.setObjectName("dialog_progress")
        dialog_progress.resize(401, 165)
        self.gridLayout = QtGui.QGridLayout(dialog_progress)
        self.gridLayout.setObjectName("gridLayout")
        self.lblFileName = QtGui.QLabel(dialog_progress)
        self.lblFileName.setText("")
        self.lblFileName.setObjectName("lblFileName")
        self.gridLayout.addWidget(self.lblFileName, 0, 0, 1, 2)
        self.pbarFileSize = QtGui.QProgressBar(dialog_progress)
        self.pbarFileSize.setProperty("value", 0)
        self.pbarFileSize.setObjectName("pbarFileSize")
        self.gridLayout.addWidget(self.pbarFileSize, 1, 0, 1, 2)
        self.label_2 = QtGui.QLabel(dialog_progress)
        self.label_2.setObjectName("label_2")
        self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
        self.pbarTotal = QtGui.QProgressBar(dialog_progress)
        self.pbarTotal.setProperty("value", 0)
        self.pbarTotal.setObjectName("pbarTotal")
        self.gridLayout.addWidget(self.pbarTotal, 3, 0, 1, 2)
        self.lblTotal = QtGui.QLabel(dialog_progress)
        self.lblTotal.setText("")
        self.lblTotal.setObjectName("lblTotal")
        self.gridLayout.addWidget(self.lblTotal, 4, 0, 1, 2)
        spacerItem = QtGui.QSpacerItem(213, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem, 6, 0, 1, 1)
        spacerItem1 = QtGui.QSpacerItem(20, 5, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem1, 5, 1, 1, 1)
        self.btnPbarCancel = QtGui.QPushButton(dialog_progress)
        self.btnPbarCancel.setObjectName("btnPbarCancel")
        self.gridLayout.addWidget(self.btnPbarCancel, 6, 1, 1, 1)

        self.retranslateUi(dialog_progress)
        QtCore.QMetaObject.connectSlotsByName(dialog_progress)

    def retranslateUi(self, dialog_progress):
        dialog_progress.setWindowTitle(QtGui.QApplication.translate("dialog_progress", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
        self.label_2.setText(QtGui.QApplication.translate("dialog_progress", "Total:", None, QtGui.QApplication.UnicodeUTF8))
        self.btnPbarCancel.setText(QtGui.QApplication.translate("dialog_progress", "Cancel", None, QtGui.QApplication.UnicodeUTF8))

class Ui_dialog_file(object):
    def setupUi(self, dialog_file):
        dialog_file.setObjectName(_fromUtf8("dialog_file"))
        dialog_file.resize(101, 59)
        self.btnCreate = QtGui.QPushButton(dialog_file)
        self.btnCreate.setGeometry(QtCore.QRect(10, 20, 77, 25))
        self.btnCreate.setObjectName(_fromUtf8("btnCreate"))
        self.retranslateUi(dialog_file)
        QtCore.QMetaObject.connectSlotsByName(dialog_file)

    def retranslateUi(self, dialog_file):
        dialog_file.setWindowTitle(QtGui.QApplication.translate("dialog_file", "file", None, QtGui.QApplication.UnicodeUTF8))
        self.btnCreate.setText(QtGui.QApplication.translate("dialog_file", "Create", None, QtGui.QApplication.UnicodeUTF8))

class ProgressDialog(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent = None)
        self.ui = Ui_dialog_progress()
        self.ui.setupUi(self)
#        self.setWindowModality(QtCore.Qt.ApplicationModal)

class MyThread(QtCore.QThread):
    trigger = QtCore.pyqtSignal()
    updateFPD = QtCore.pyqtSignal()
    updateTPD = QtCore.pyqtSignal()
    def __init__(self, parent=None):
        super(MyThread, self).__init__(parent)
        self.pd = ProgressDialog()
        signal = QtCore.SIGNAL("clicked()")
        self.pd.ui.btnPbarCancel.connect(self.pd.ui.btnPbarCancel, signal, self.abort)
        self.aborted= False

    def run(self):
        self.trigger.emit()

    def abort(self):
        self.aborted = True
        print "aborted"
        self.pd.close()

    def setup(self, no):
        self.threadNo = no
        self.name = "Thread %d"%self.threadNo

class Main(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        self.ui = Ui_dialog_file()
        self.ui.setupUi(self)
        self.ui.btnCreate.clicked.connect(self.start_threads)
        self.count = 0
        self.threadPool = []

    def start_threads(self):
        self.mythread = MyThread(self)
        self.mythread.setup(self.count)
        self.count += 1
        self.mythread.trigger.connect(self.pdialog)
        self.mythread.start()
        self.threadPool.append(self.count)

    def abort(self):
        self.mythread.stop()

    def pdialog(self):
        self.mythread.pd.show()
        i = 1
        self.mythread.pd.ui.pbarTotal.setValue(0)
        self.mythread.pd.ui.pbarFileSize.setValue(0)
        self.mythread.pd.setWindowTitle(self.mythread.name)
        j = 1
        while i < 100:
            while j <= 100:
                self.mythread.pd.ui.lblFileName.setText(self.mythread.name)
                self.mythread.pd.ui.pbarFileSize.setValue(j)
                print "name: %s, fileprogress: %d"%(self.mythread.name,j)
                QtGui.qApp.processEvents()
                j += 1
            i += 1
            j = 1
            self.mythread.pd.ui.pbarTotal.setValue(i)
            print "name: %s, total progress %d"%(self.mythread.name, i)
            QtGui.qApp.processEvents()
            if self.mythread.aborted:
                return
        self.mythread.pd.close()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    mainwindow = Main()
    mainwindow.show()
    sys.exit(app.exec_())
导入系统 从PyQt4导入QtGui、QtCore 尝试: _fromUtf8=QtCore.QString.fromUtf8 除属性错误外: _fromUtf8=λs:s 类Ui_对话框_进度(对象): def setupUi(自我、对话框和进度): dialog\u progress.setObjectName(“dialog\u progress”) 对话框\进度。调整大小(401165) self.gridLayout=QtGui.QGridLayout(对话框\u进度) self.gridLayout.setObjectName(“gridLayout”) self.lblFileName=QtGui.QLabel(对话框\u进度) self.lblFileName.setText(“”) self.lblFileName.setObjectName(“lblFileName”) self.gridLayout.addWidget(self.lblFileName,0,0,1,2) self.pbarFileSize=QtGui.QProgressBar(对话框\u进度) self.pbarFileSize.setProperty(“值”,0) self.pbarFileSize.setObjectName(“pbarFileSize”) self.gridLayout.addWidget(self.pbarFileSize,1,0,1,2) self.label_2=QtGui.QLabel(对话框_进度) self.label_2.setObjectName(“label_2”) self.gridLayout.addWidget(self.label_2,2,0,1,1) self.pbarTotal=QtGui.QProgressBar(对话框\u进度) self.pbarTotal.setProperty(“值”,0) self.pbarTotal.setObjectName(“pbarTotal”) self.gridLayout.addWidget(self.pbarTotal,3,0,1,2) self.lblTotal=QtGui.QLabel(对话框进度) self.lblTotal.setText(“”) self.lblTotal.setObjectName(“lblTotal”) self.gridLayout.addWidget(self.lblTotal,4,0,1,2) SpaceItem=QtGui.QSpacerItem(213,20,QtGui.QSizePolicy.expansing,QtGui.QSizePolicy.Minimum) self.gridLayout.addItem(间隔项,6,0,1,1) SpaceItem1=QtGui.QSpacerItem(20,5,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Expanding) self.gridLayout.addItem(间隔项1,5,1,1,1) self.btnPbarCancel=QtGui.QPushButton(对话框\u进度) self.btnPbarCancel.setObjectName(“btnPbarCancel”) self.gridLayout.addWidget(self.btnPbarCancel,6,1,1) 自重传(对话框\进程) QtCore.QMetaObject.connectSlotsByName(对话框\u进度) def重新传输(自身、对话框和进度): dialog_progress.setWindowTitle(QtGui.QApplication.translate(“dialog_progress”,“dialog”,None,QtGui.QApplication.UnicodeUTF8)) self.label_2.setText(QtGui.QApplication.translate(“对话进度”,“总计:”,无,QtGui.QApplication.UnicodeUTF8)) self.btnPbarCancel.setText(QtGui.QApplication.translate(“对话进程”,“取消”,无,QtGui.QApplication.UnicodeUTF8)) 类Ui_对话框_文件(对象): def setupUi(自身,对话框文件): dialog\u file.setObjectName(\u来自UTF8(“dialog\u文件”)) 对话框_文件。调整大小(101,59) self.btnCreate=QtGui.QPushButton(对话框文件) self.btnCreate.setGeometry(QtCore.QRect(10,20,77,25)) self.btnCreate.setObjectName(_fromUtf8(“btnCreate”)) 自重传(对话框文件) QtCore.QMetaObject.connectSlotsByName(对话框文件) def重新传输(自身,对话框文件): dialog_file.setWindowTitle(QtGui.QApplication.translate(“dialog_file”,“file”,无,QtGui.QApplication.UnicodeUTF8)) self.btnCreate.setText(QtGui.QApplication.translate(“dialog_file”,“Create”,None,QtGui.QApplication.UnicodeUTF8)) 类进程对话框(QtGui.QDialog): def uuu init uuu(self,parent=None): QtGui.QDialog.\uuuu init\uuuu(self,parent=None) self.ui=ui\u dialog\u progress() self.ui.setupUi(self) #self.setWindowModal(QtCore.Qt.ApplicationModel) 类MyThread(QtCore.QThread): 触发器=QtCore.pyqtSignal() updateFPD=QtCore.pyqtSignal() updateTPD=QtCore.pyqtSignal() def uuu init uuu(self,parent=None): 超级(MyThread,self)。\uuuuu init\uuuuuuuu(父级) self.pd=ProgressDialog() signal=QtCore.signal(“单击()”) self.pd.ui.btnPbarCancel.connect(self.pd.ui.btnPbarCancel,signal,self.abort) self.aborted=False def运行(自): self.trigger.emit() def中止(自我): self.aborted=True 打印“中止” self.pd.close() def设置(自身,否): self.threadNo=否 self.name=“线程%d”%self.threadNo 主类(QtGui.QDialog): def uuu init uuu(self,parent=None): 超级(主、自).\uuuu初始化\uuuuuu(父) self.ui=ui\u对话框\u文件() self.ui.setupUi(self) self.ui.btnCreate.clicked.connect(self.start\u线程) self.count=0 self.threadPool=[] def start_线程(自): self.mythread=mythread(self) self.mythread.setup(self.count) self.count+=1 self.mythread.trigger.connect(self.pdialog) self.mythread.start() self.threadPool.append(self.count) def中止(自我): self.mythread.stop() def pdialog(自): self.mythread.pd.show() i=1 self.mythread.pd.ui.pbarTotal.setValue(0) self.mythread.pd.ui.pbarFileSize.setValue(0) self.mythread.pd.setWindowTitle(self.mythread.name) j=1 当我<100时:
而j小部件应该只由主ui线程(即控制主事件循环的线程)控制。如果一个小部件存在于主线程之外,那么它很可能不会收到任何更新,也不会发布任何事件,例如被单击。不要让线程拥有和/或操作ui小部件。在这种情况下,您根本不需要
MyThread

让我举个例子

import time
import sys
from PyQt4 import QtGui, QtCore


class MyThread(QtCore.QThread):

    progress_changed = QtCore.pyqtSignal(object)

    def run(self):
        for x in range(101):
            #we do not interect with the progress bar directly
            self.progress_changed.emit(x)
            time.sleep(0.1)


class MyWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.progress_thread1 = MyThread()
        self.progress_thread2 = MyThread()

        self.progress_bar1 = QtGui.QProgressBar()
        self.progress_bar1.setMinimum(0)
        self.progress_bar1.setMaximum(100)

        self.progress_bar2 = QtGui.QProgressBar()
        self.progress_bar2.setMinimum(0)
        self.progress_bar2.setMaximum(100)


        """
        the progress is emmited through the thread's progress_changed signal
        we connect that signal to our updateProgress method which will
        be used to set the progress_bar's value

        you can also just connect it directly to the progress bar's setValue method
        self.progress_thread.progress_changed.connect(self.progress_bar.setValue)
        """
        self.progress_thread1.progress_changed.connect(self.updateProgress1)

        self.progress_thread2.progress_changed.connect(self.updateProgress2)

        mainLayout = QtGui.QVBoxLayout()
        mainLayout.addWidget(self.progress_bar1)
        mainLayout.addWidget(self.progress_bar2)

        self.setLayout(mainLayout)

        self.progress_thread1.start()
        self.progress_thread2.start()


    def updateProgress1(self, progress):
        self.progress_bar1.setValue(progress)

    def updateProgress2(self, progress):
        self.progress_bar2.setValue(progress)



if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    widget = MyWidget()
    widget.show()
    r = app.exec_()
    sys.exit(r)

将此复制到一个空的python脚本并运行它。

Vikki,但如果我想使用MyThread执行此操作。所以,你能修改现有的代码,使其
import time
import sys
from PyQt4 import QtGui, QtCore


class MyThread(QtCore.QThread):

    progress_changed = QtCore.pyqtSignal(object)

    def run(self):
        for x in range(101):
            #we do not interect with the progress bar directly
            self.progress_changed.emit(x)
            time.sleep(0.1)


class MyWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.progress_thread1 = MyThread()
        self.progress_thread2 = MyThread()

        self.progress_bar1 = QtGui.QProgressBar()
        self.progress_bar1.setMinimum(0)
        self.progress_bar1.setMaximum(100)

        self.progress_bar2 = QtGui.QProgressBar()
        self.progress_bar2.setMinimum(0)
        self.progress_bar2.setMaximum(100)


        """
        the progress is emmited through the thread's progress_changed signal
        we connect that signal to our updateProgress method which will
        be used to set the progress_bar's value

        you can also just connect it directly to the progress bar's setValue method
        self.progress_thread.progress_changed.connect(self.progress_bar.setValue)
        """
        self.progress_thread1.progress_changed.connect(self.updateProgress1)

        self.progress_thread2.progress_changed.connect(self.updateProgress2)

        mainLayout = QtGui.QVBoxLayout()
        mainLayout.addWidget(self.progress_bar1)
        mainLayout.addWidget(self.progress_bar2)

        self.setLayout(mainLayout)

        self.progress_thread1.start()
        self.progress_thread2.start()


    def updateProgress1(self, progress):
        self.progress_bar1.setValue(progress)

    def updateProgress2(self, progress):
        self.progress_bar2.setValue(progress)



if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    widget = MyWidget()
    widget.show()
    r = app.exec_()
    sys.exit(r)