2014-09-20 55 views
0

下面是代码:为什么我不能在类的成员函数中初始化QThread?

########################################################## 
######## 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件作品OK,版本2给出了这样的错误(而破碎瞬间,当处理按钮被按下):

QThread: Destroyed while thread is still running 

Process finished with exit code 139 
+0

错误消息几乎无法使事情更加明显,尤其是因为这两个例子之间的唯一真正的区别在于一个保持对工人的引用线程,而另一个没有。另外,你应该知道使用[直接连接信号是不安全的](https://qt-project.org/doc/qt-4.8/threads-qobject.html#signals-and-slots-across-线程)。 – ekhumoro 2014-09-20 17:50:54

回答

2

发生这种情况,因为不像threading.Thread对象,QThread对象一旦超出范围就会被销毁。在你的例子中,当work结束时wt超出范围,因此对象被破坏。为了避免这种情况,您需要持续参考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) 
相关问题