为qt应用程序使用线程

时间:2013-04-08 03:47:23

标签: 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

#       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的值为{{1}}。

用它作为参考 http://joplaete.wordpress.com/2010/07/21/threading-with-pyqt4/

1 个答案:

答案 0 :(得分:2)

我认为当你尝试在第二个文件中调用thread.start()时(通过self.btnSgn.emit())它不起作用的原因是线程对象超出了 init 功能,您可以在其中创建它。所以你在已经删除的线程上调用start()。

只需更改主题 - > self.thread(即使线程对象成为WindowClass对象的一个​​成员)在我尝试它时工作正常,因为线程会保持活着直到程序结束。