Python 如果将QThread创建为局部变量,为什么它的行为会有所不同

Python 如果将QThread创建为局部变量,为什么它的行为会有所不同,python,pyqt,pyqt4,qthread,Python,Pyqt,Pyqt4,Qthread,如果将QThread创建为局部变量,我会发现一个奇怪的行为 例如,下面的代码将作为单线程工作,这意味着我需要等待10秒,结果就会出来 但如果我将线程从局部变量更改为成员变量,它将作为多线程工作 怎么样?谁能给我一些提示吗 class UI(): def __init__(self): self.app = QtGui.QApplication(sys.argv) self.dialog = QtGui.QDialog() self.ui =

如果将QThread创建为局部变量,我会发现一个奇怪的行为

例如,下面的代码将作为单线程工作,这意味着我需要等待10秒,结果就会出来

但如果我将线程从局部变量更改为成员变量,它将作为多线程工作

怎么样?谁能给我一些提示吗

class UI():
    def __init__(self):
        self.app = QtGui.QApplication(sys.argv)
        self.dialog = QtGui.QDialog()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self.dialog)
        self.ui.btn.clicked.connect(self.btnclick)

    def run(self):
        self.dialog.show()
        sys.exit(self.app.exec_())

    def btnclick(self):
        ## if change to self.thread, the behavior changes!!
        signal = QtCore.SIGNAL("Log(QString)")
        thread = testThread(signal)  
        QtCore.QObject.connect(thread, signal, self.output)
        thread.start()

    def output(self, txt):
        self.ui.logText.append(str(txt))

class testThread(QThread):
    def __init__(self, signal):
        QThread.__init__(self)
        self.signal = signal

    def __del__(self):
        self.wait()

    def run(self):
        for i in range(10):
            time.sleep(1)
            self.output(str(i))

    def output(self, txt):
        self.emit(self.signal, txt)


if __name__ == "__main__":
    ui = UI()
    ui.run()

需要指出的问题是,它是一个局部变量,在启动
QThread
后不久将被销毁,因此
QThread
处理的线程(QThread不是线程,它是线程处理程序)将被删除,并且在使用
wait()
时,预期
run()
方法将在生成GUI冻结的主线程中执行

因此,解决方案是延长变量线程的生命周期,一种方法是指出它是有效的:使其成为类的成员,但还有另一种方法仅适用于QObjects作为QThread,即传递一个父对象(父对象必须是另一个QObject),将对象的生命周期延长到与父对象相同的容量,因此,我将使用对话框

最后,现在不建议动态创建信号,最好将其作为类的一部分创建,也用于您必须使用的连接


我猜问题是testThread中的self.wait(),因为当函数结束时,局部变量将被销毁,它将调用testThread。u del_u()。但是如果我不想使用局部变量,有没有更好的办法?什么是
setSignal
?,您的代码有几个类似的错误,无法验证您发出的错误谢谢您的精彩解释!!知道了!
class UI():
    def __init__(self):
        self.app = QtGui.QApplication(sys.argv)
        self.dialog = QtGui.QDialog()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self.dialog)
        self.ui.btn.clicked.connect(self.btnclick)
        self.dialog.show()

    def btnclick(self):
        thread = testThread(self.dialog)  
        thread.signal.connect(self.output)
        thread.start()

    def output(self, txt):
        self.ui.logText.append(str(txt))

class testThread(QtCore.QThread):
    signal = QtCore.pyqtSignal(str)

    def __del__(self):
        self.wait()

    def run(self):
        for i in range(10):
            QtCore.QThread.sleep(1)
            self.output(str(i))

    def output(self, txt):
        self.signal.emit(txt)

if __name__ == '__main__':
    ui = UI()
    app = QtGui.QApplication.instance()
    if app is not None:
        sys.exit(app.exec_())