睡觉工作线程导致主要gui冻结

时间:2013-05-27 09:37:41

标签: python pyqt

睡觉工作线程导致主gui冻结。

我想做的是:

  1. 睡眠工作线程(MyThread)并在之后开始下一次迭代 一段时间。
  2. MyThread进入睡眠状态后,单击取消,然后取消 正在进行中。
  3. 在我的情况下,当MyThread再次唤醒时,主操作被取消。我希望它立即被取消。

    import sys
    from PyQt4 import QtGui, QtCore
    import time
    
    
    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(int, QtCore.QString)
        updateTPD = QtCore.pyqtSignal(int, QtCore.QString)
        showpdSignal = QtCore.pyqtSignal(bool)
    
        def __init__(self, parent=None, no=0):
            super(MyThread, self).__init__(parent)
            self.aborted= False
            self.threadNo = no
    #        self.name = "Thread %d"%self.threadNo
    
        def run(self):
            self.trigger.emit()
    
        def emitSignals(self, iprogress = -99, tprogress = -99,\
                    updateFPDSignal = True, updateTPDSignal = None,\
                    showpdSignal = False, peSignal = None, msg = None
                    ):
            if updateFPDSignal:
                self.updateFPD.emit(iprogress, msg)
            if updateTPDSignal:
                self.updateTPD.emit(tprogress, msg)
            if showpdSignal:
                self.showpdSignal.emit(True)
            else:
                self.showpdSignal.emit(False)
            if peSignal:
                QtGui.QApplication.processEvents()
    
        def abort(self):
            self.aborted = True
            print "aborted"
    
        def stop(self):
            self.terminate()
    
    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
    
        def start_threads(self):
            self.mythread = MyThread()
            self.pd = ProgressDialog()
            signal = QtCore.SIGNAL("clicked()")
            self.pd.ui.btnPbarCancel.connect(self.pd.ui.btnPbarCancel, signal, self.abort)
            self.mythread.trigger.connect(self.pdialog)
            self.mythread.updateFPD.connect(self.updateFileProgress)
            self.mythread.updateTPD.connect(self.updateTotalProgress)
            self.mythread.start()
    
        def abort(self):
            self.pd.close()
            self.mythread.aborted = True
    
        def updateFileProgress(self, j, name):
            self.pd.ui.lblFileName.setText(name)
            self.pd.ui.pbarFileSize.setValue(j)
            print "name: %s, fileprogress: %d"%(name,j)
    
        def updateTotalProgress(self, i, name):
            self.pd.ui.pbarTotal.setValue(i)
            print "name: %s, total progress %d"%(name, i)
    
        def showProgressDialog(self, show):
            if show:
                self.pd.show()
            else:
                self.pd.close()
    
        def pdialog(self):
            for k in range(3):
                self.pd.show()
                i = 1
                self.mythread.emitSignals(iprogress =0 , tprogress = 0, updateFPDSignal = True,
                                          updateTPDSignal = True, showpdSignal = True, msg = "")
                j = 1
                while i < 100:
                    while j <= 100:
                        print j
                        self.mythread.emitSignals(iprogress = j, updateFPDSignal = True,\
                                                  peSignal = True, msg = "")
                        j += 1
                    i += 1
                    j = 1
                    self.mythread.emitSignals(tprogress = i, updateTPDSignal = True,\
                                                  peSignal = True, msg = "")
                    if self.mythread.aborted:
                        return
                self.mythread.sleep(10)
                self.pd.close()
    
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        mainwindow = Main()
        mainwindow.show()
        sys.exit(app.exec_())
    

1 个答案:

答案 0 :(得分:0)

您的MyThread并没有真正做任何事情,因为您可以看到它是run方法。所有其他方法仍然从主线程调用,因此仍然在那里发生。

请阅读Qt Threading Basics,特别是关于QObjects和线程的部分,它应该清楚说明为什么你使用QThreads的方式正在工作。

您可能真正想做的是:

  • 让您的员工成为正常的QObject
  • 开始新的QThread
  • 使用moveToThread方法
  • 将您的工作人员移至该主题
  • 使用信号
  • 从主线程与其进行交互