为什么我不能在类的成员函数中初始化QThread?

时间:2014-09-20 15:46:23

标签: python multithreading qt pyside

以下是代码:

##########################################################
######## Version 1 (works)
##########################################################
#!/usr/bin/env python3


from ui.qthreadtest import Ui_QthreadTest
from PySide import QtCore, QtGui
import time

class Md(QtGui.QDialog):
    def __init__(self):
        super().__init__()
        self.prcsbtn = QtGui.QPushButton("Process")
        self.prcsedit = QtGui.QLineEdit()
        layout = QtGui.QHBoxLayout()
        layout.addWidget(self.prcsedit)
        layout.addWidget(self.prcsbtn)
        self.setLayout(layout)
        self.prcsbtn.clicked.connect(self.work)

        self.wt = Worker()

    def work(self):
        self.wt.start()
        # the DirectConnection option demands the slot to be triggered immediately
        self.wt.workFinished.connect(self.changeText, QtCore.Qt.DirectConnection)

    def changeText(self):
        self.prcsedit.setText("Work finished!")

class Worker(QtCore.QThread):
    workFinished = QtCore.Signal()
    def __init__(self):
        super().__init__()

    def run(self):
        time.sleep(2)
        self.workFinished.emit()

import sys
app = QtGui.QApplication(sys.argv)
md = Md()
md.show()
sys.exit(app.exec_())


##########################################################
######## Version 2 (doesn't work)    
##########################################################

#!/usr/bin/env python3


from ui.qthreadtest import Ui_QthreadTest
from PySide import QtCore, QtGui
import time

class Md(QtGui.QDialog):
    def __init__(self):
        super().__init__()
        self.prcsbtn = QtGui.QPushButton("Process")
        self.prcsedit = QtGui.QLineEdit()
        layout = QtGui.QHBoxLayout()
        layout.addWidget(self.prcsedit)
        layout.addWidget(self.prcsbtn)
        self.setLayout(layout)
        self.prcsbtn.clicked.connect(self.work)


    def work(self):
        # the worker thread initialized in a member function won't work.
        wt = Worker()
        wt.start()
        # the DirectConnection option demands the slot to be triggered immediately
        wt.workFinished.connect(self.changeText, QtCore.Qt.DirectConnection)

    def changeText(self):
        self.prcsedit.setText("Work finished!")

class Worker(QtCore.QThread):
    workFinished = QtCore.Signal()
    def __init__(self):
        super().__init__()

    def run(self):
        time.sleep(2)
        self.workFinished.emit()

import sys
app = QtGui.QApplication(sys.argv)
md = Md()
md.show()
sys.exit(app.exec_())

版本1工作正常,版本2发出此错误(按下“处理”按钮时立即压缩):

QThread: Destroyed while thread is still running

Process finished with exit code 139

1 个答案:

答案 0 :(得分:3)

这种情况正在发生,因为与threading.Thread对象不同,QThread个对象一旦超出范围就会被销毁。在您的示例中,wtwork结束时超出范围,因此对象将被销毁。为避免这种情况,您需要持续引用wt。一种方法是将其作为实例变量:

def work(self):
    self.wt = Worker()
    self.wt.start()
    # the DirectConnection option demands the slot to be triggered immediately
    self.wt.workFinished.connect(self.changeText, QtCore.Qt.DirectConnection)