发送终端后,Qthread不会停止

2024-10-01 15:43:53 发布

您现在位置:Python中文网/ 问答频道 /正文

以下代码的问题是工作线程在按下cancel按钮后没有终止,def pdialog(self)直到while循环结束才停止。我想停止进度条打印进度,因此后台进程。在

import sys
from PyQt4 import QtGui, QtCore
import time

#from t6 import Ui_dialog_progress
#from t6 import Ui_dialog_file

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()
    updatePD = QtCore.pyqtSignal()
    def __init__(self, parent=None):
        super(MyThread, self).__init__(parent)

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

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)

    def start_threads(self):
        self.mythread = MyThread(self)
        self.mythread.trigger.connect(self.pdialog)
        self.connect(self.mythread, QtCore.SIGNAL("updateFileProgress(int)"), self.updateFileProgress)
        self.connect(self.mythread, QtCore.SIGNAL("updateTotalProgress(int)"), self.updateTotalProgress)
        self.pd = ProgressDialog()
        signal = QtCore.SIGNAL("clicked()")
        self.pd.ui.btnPbarCancel.connect(self.pd.ui.btnPbarCancel, signal, self.abort)
        self.mythread.start()

    def abort(self):
        self.pd.close()
        self.mythread.terminate()

    def updateFileProgress(self, j):
        self.pd.ui.pbarFileSize.setValue(j)
        print j

    def updateTotalProgress(self, i):
        self.pd.ui.pbarTotal.setValue(i)
        print i

    def pdialog(self):
        self.pd.show()
        i = 1
        self.pd.ui.pbarTotal.setValue(0)
        self.pd.ui.pbarFileSize.setValue(0)
        j = 1
        while i < 100:
            while j <= 100:
                time.sleep(0.01)
                self.mythread.emit(QtCore.SIGNAL("updateFileProgress(int)"), j)
                QtGui.qApp.processEvents()
                j += 1
            i += 1
            j = 1
            self.mythread.emit(QtCore.SIGNAL("updateTotalProgress(int)"), i)
            QtGui.qApp.processEvents()
        self.pd.close()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    mainwindow = Main()
    mainwindow.show()
    sys.exit(app.exec_())

Tags: selfnoneuideffiledialogpdprogress
1条回答
网友
1楼 · 发布于 2024-10-01 15:43:53

不要使用terminate()终止线程。在

http://qt-project.org/doc/qt-4.8/qthread.html#terminate

void QThread::terminate () [slot]

Terminates the execution of the thread. The thread may or may not be terminated immediately, depending on the operating systems scheduling policies. Use QThread::wait() after terminate() for synchronous termination.

When the thread is terminated, all threads waiting for the thread to finish will be woken up.

Warning: This function is dangerous and its use is discouraged. The thread can be terminated at any point in its code path. Threads can be terminated while modifying data. There is no chance for the thread to clean up after itself, unlock any held mutexes, etc. In short, use this function only if absolutely necessary.

有许多温和的方法来阻止线程。
例如,可以使用标志变量来通知辅助函数停止。在

def start_threads(self):
    self.end_flag = False
    self.mythread = MyThread(self)
    self.mythread.trigger.connect(self.pdialog)
    self.connect(self.mythread, QtCore.SIGNAL("updateFileProgress(int)"), self.updateFileProgress)
    self.connect(self.mythread, QtCore.SIGNAL("updateTotalProgress(int)"), self.updateTotalProgress)
    self.pd = ProgressDialog()
    signal = QtCore.SIGNAL("clicked()")
    self.pd.ui.btnPbarCancel.connect(self.pd.ui.btnPbarCancel, signal, self.abort)
    self.mythread.start()

def abort(self):
    self.pd.close()
    #self.mythread.terminate()
    self.end_flag = True

def pdialog(self):
    self.pd.show()
    i = 1
    self.pd.ui.pbarTotal.setValue(0)
    self.pd.ui.pbarFileSize.setValue(0)
    j = 1
    while i < 100:
        while j <= 100:
            if self.end_flag:
                self.pd.close()
                return
            time.sleep(0.01)
            self.mythread.emit(QtCore.SIGNAL("updateFileProgress(int)"), j)
            QtGui.qApp.processEvents()
            j += 1
        i += 1
        j = 1
        self.mythread.emit(QtCore.SIGNAL("updateTotalProgress(int)"), i)
        QtGui.qApp.processEvents()
    self.pd.close()

相关问题 更多 >

    热门问题