[英]Sleeping the worker thread causes main gui to freeze
Sleeping the worker thread causes main gui to freeze. 休眠工作线程会导致主GUI冻结。
What I want to do is: 我想做的是:
In my case the main operation gets canceled when MyThread
wakes up again. 就我而言,当MyThread
再次唤醒时,主要操作将被取消。 I wanted it to be cancelled immediately. 我希望它立即被取消。
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_())
Your MyThread
doesn't really do anything, as you can see if you look at it's run
method. MyThread
实际上并没有做任何事情,因为您可以查看它的run
方法。 All other methods are still called from the main thread and therefore still happen there. 所有其他方法仍从主线程调用,因此仍在此发生。
Please read Qt Threading Basics , specially the section about QObjects and threads, it should make it clear why the way you're using QThreads is ont working. 请阅读Qt Threading Basics ,特别是有关QObjects和线程的部分,它应该清楚说明为什么您使用QThreads的方式不能正常工作。
What you probably really want to do is: 您可能真正想做的是:
moveToThread
method 使用moveToThread
方法将您的工作程序移动到该线程
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.