2014-07-15 83 views
1

我想了解線程是如何工作的,而且我遇到了這個問題。這是我的程序解釋: 我在pyqt中做了一個簡單的GUI,它使用QObject作爲工人類。當我按下按鈕時,gui從列表中讀取一個隨機值並將其傳遞給線程,打印下一個五位數字 。當線程完成工作時,它將數據傳遞給gui。現在我想讓GUI自動重新啓動一個具有新的起始值的新線程。我可以通過再次按開始重新啓動線程,但是我需要在沒有人工交互的情況下啓動它。有沒有 任何方法?PyQt Qthread自動重啓

在此先感謝

from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
import time 
import sys 
import numpy as np 



class SomeObject(QObject): 

    finished = pyqtSignal(object) 
    valore = pyqtSignal(object) 
    vector = pyqtSignal(object) 

    def __init(): 
     super(SomeObject, self).__init__() 

    def longRunning(self): 
     vec = [] 
     end = self.count + 5 
     while self.count < end: 
      time.sleep(1) 
      vec.append(self.count) 
      self.valore.emit(self.count) 
      self.count += 1 
     self.finished.emit(vec) 
     #self.vector.emit() 

    def setCount(self, num): 
     self.count = num 

class GUI(QDialog): 

    def __init__(self, parent = None): 
     super(GUI, self).__init__(parent) 
     #declare QThread object 
     self.objThread = QThread() 
     #declare SomeObject type, and move it to thread 
     self.obj = SomeObject() 
     self.obj.moveToThread(self.objThread) 
     #connect finished signal to nextVector method 
     self.obj.finished.connect(self.nextVector) 
     #connect valore to self.prova method 
     self.obj.valore.connect(self.prova) 
     #self.obj.vector.connect(self.nextVector) 
     #Connect thread.start to the method long running 
     self.objThread.started.connect(self.obj.longRunning) 

     botton = QPushButton("start") 
     self.connect(botton, SIGNAL("clicked()"), self.showcount) 
     box = QHBoxLayout() 
     box.addWidget(botton)   
     self.setLayout(box) 

     #a list of random number 
     a = np.random.randint(10, size = 5) 
     self.iter = iter(a) 

    def showcount(self): 
     """ 
     When botton clicked, read the next value from iter, pass it to 
     setCount and when start the thread 
     """   
     try: 
      a = self.iter.next() 
      print a 
      self.obj.setCount(a)   
      self.objThread.start() 
     except StopIteration: 
      print "finito" 
     #self.obj.setCount(a)   
     #self.objThread.start() 
     #print self.objThread.currentThreadId() 

    def prova(self, value): 
     """ 
     Connected to signal valore, print the value 
     """ 
     print value 

    def nextVector(self, vec): 
     """ 
     Print the whole vector 
     """ 
     print vec 
     self.objThread.quit() 
     try: 
      a = self.iter.next() 
      print a 
      self.obj.setCount(a)   
      self.objThread.start() 
     except StopIteration: 
      print "finito" 

app = QApplication(sys.argv) 
form = GUI() 
form.show() 
app.exec_()  

回答

1

你已經擁有它成立。當線程完成後,它會發出調用nextVector方法的完成信號,所以只需在nextVector的末尾調用start方法即可。

def nextVector(self, vec): 
    ... 
    self.showcount() 
# end nextVector 

您可能還希望更改爲新的信號連接爲您QPushButton

button.clicked.connect(self.showcount) 
+0

我試了一下,但是當線程發出結束信號程序召回showcount方法沒有發生。我找到一個解決方案,用self.obj.finished.connect(self.objThread.quit)和self.objThread.finished.connect(self.nextVector)替換self.obj.finished.connect(self.nextVector),但老實說我沒有區別 – GiovanniPi

+0

噢,另外需要補充的是一個線程只能調用一次run方法,然後你應該調用join方法來釋放該線程。如果你想多次運行它,你將不得不重新創建線程。對不起,我以爲你每次都在你的showcount方法中創建一個新的線程。唯一的另一種解決方法是使用鎖定的可鎖定線程類。 http://stackoverflow.com/questions/8103847/pausing-two-python-threads-while-a-third-one-does-stuff-withlocks – HashSplat

+0

所以問題是,我試圖重用一個線程,取而代之的是一個新的,對嗎?您發佈的鏈接很有趣,但我更喜歡使用QObject/Qthread方法 – GiovanniPi