2013-04-08 75 views
0

我有以下兩個文件:使用線程的Qt應用程序

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

以此爲參考 http://joplaete.wordpress.com/2010/07/21/threading-with-pyqt4/

回答

2

我想原因是當您嘗試調用thread.start()在你的第二個文件不工作(通過self.btnSgn.emit())是線程對象超出了您創建它的功能之外的範圍init函數。所以你在一個已經刪除的線程上調用start()。

只是改變線程 - > self.thread(即使線程對象成爲WindowClass對象的成員)在我嘗試時正常工作,因爲線程會一直保持活動狀態直到程序結束。