Python 在qt应用程序中使用线程

Python 在qt应用程序中使用线程,python,pyqt,qthread,Python,Pyqt,Qthread,我有以下两个文件: import sys import time from PyQt4 import QtGui, QtCore import btnModule class WindowClass(QtGui.QWidget): def __init__(self): super(WindowClass, self).__init__() self.dataLoaded = None # Widgets # Button

我有以下两个文件:

import sys
import time
from PyQt4 import QtGui, QtCore

import btnModule

class WindowClass(QtGui.QWidget):

    def __init__(self):
        super(WindowClass, self).__init__()
        self.dataLoaded = None

#       Widgets

#       Buttons
        thread = WorkerForLoop(self.runLoop)
#        thread.start()
        self.playBtn    = btnModule.playpauselBtnClass \
                            ('Play', thread.start)            
#       Layout
        layout = QtGui.QHBoxLayout()
        layout.addWidget(self.playBtn)
        self.setLayout(layout)

#       Window Geometry
        self.setGeometry(100, 100, 100, 100)

    def waitToContinue(self):
        print self.playBtn.text()
        while (self.playBtn.text() != 'Pause'):
            pass

    def runLoop(self):
        for ii in range(100):
            self.waitToContinue()
            print 'num so far: ', ii
            time.sleep(0.5)

class WorkerForLoop(QtCore.QThread):
    def __init__(self, function, *args, **kwargs):
        super(WorkerForLoop, self).__init__()
        self.function = function
        self.args = args
        self.kwargs = kwargs

    def __del__(self):
        self.wait()

    def run(self):
        print 'let"s run it'
        self.function(*self.args, **self.kwargs)
        return



if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)

    wmain = WindowClass()
    wmain.show()

    sys.exit(app.exec_())
以及第二个文件btnModule.py:

from PyQt4 import QtGui, QtCore

class playpauselBtnClass(QtGui.QPushButton):

    btnSgn = QtCore.pyqtSignal()

    def __init__(self, btnName, onClickFunction):
        super(playpauselBtnClass, self).__init__(btnName)

        self.clicked.connect(self.btnPressed)
        self.btnSgn.connect(onClickFunction)

    def btnPressed(self):
        if self.text() == 'Play':
            self.setText('Pause')
            self.btnSgn.emit()
            print 'Changed to pause and emited signal'
        elif self.text() == 'Pause':
            self.setText('Continue')
            print 'Changed to Continue'
        elif self.text() == 'Continue':
            self.setText('Pause')
            print 'Changed to Pause'
如果在第一个文件中,我删除了
thread.start()
处的注释,它会按预期工作,启动线程,然后挂起,直到我在UI上单击
Play
。但是,我认为即使我没有在那里启动它,它也应该工作,因为信号是
btnSgn
连接到
onClickFunction
,在本例中,该函数取值
thread.start

以此作为参考

我认为,当您尝试调用第二个文件中的thread.start()时(通过self.btnSgn.emit())它不起作用的原因是thread对象超出了创建它的init函数的范围。因此,您正在对已删除的线程调用start()

只要更改thread->self.thread(即使thread对象成为WindowClass对象的成员)就可以在我尝试时正常工作,因为线程一直保持活动状态,直到程序结束