2011-09-19 46 views
0

謎一般的類型錯誤我有一個運行的QThread,但經常需要被殺死,然後重新創建。問題是我得到一個難以追蹤的類型錯誤彈出,我不知道是什麼導致它。我相信我沒有正確地退出線程或正確或一些這樣的sillyness破壞它,但我只是沒有一個線索是什麼導致了它。下面是一些代碼片段:與QThread的使用

下面的代碼一起:

class getHistory(QThread): 
    def __init__(self): 
     QThread.__init__(self) 
     self.killSwitch = 0 

    def kill(self): 
     self.killSwitch = 1 
     self.wait() 

    def run(self): 
     try: 
      for x in theloop: 
       hist = QTreeWidgetItem() 
       hist.data = dataStuff 
       self.emit(SIGNAL('histItem'), hist) 
       if self.killSwitch == 1: break     
     except: pass 
     self.emit(SIGNAL('string'), 'done') 
     return 

class Main(QtGui.QMainWindow): 
    def __init__(self, args): 
     QtGui.QMainWindow.__init__(self) 
     self.runTheThread() 

    def doFunction(self, string): 
     if not string == 'done': 
      doThreadStuff 
     else: 
      doFinishedThreadStuff 

    def runTheThread(self): 
     self.theThread= getHistory() 
     self.connect(self.theThread, QtCore.SIGNAL("string"), self.doFunction) 
     self.theThread.start() 

然後嘗試循環之前殺死它,我殺theThread與self.theThread.kill()

所有適當的除非線程被終止並重新啓動足夠快,否則我會得到一個難以追查的錯誤:

TypeError:doFunction()需要完全2個參數(1給出)

另外,在一個稍有相關的說明,它是明智/聰明/正確的檢查是否通過發射一個字符串,如「完成」,是由doFunction,還是有更好的方法來做到這一點?

作爲doFunction是一個Qt應用程序的一部分,這兩個參數是自,字符串。該代碼一直運行,直到它被垃圾郵件,真正的,只有這樣它纔會出現錯誤。

在此先感謝。

回答

2

嗯,錯誤狀態清楚:你要發送self.doFunction只有一個參數(在這種情況下,字符串「AllDone」):

self.emit(SIGNAL('string'), 'AllDone') 

,但是,我會採取一種野生的猜測(因爲你沒有分享doFunction的定義),它被定義爲採用兩個參數。所以,無論何時你發出「串」信號,你都必定會得到那個錯誤。至於信號,如果唯一的目的是喊出線程已完成運行,QThread已經有一個「完成()」信號,在運行完成時發出。只要使用它。

在一個側面說明:如果您正在使用PyQt4.5 +考慮使用new-style signal and slots。他們更pythonic。

+0

我更新了doFunction代碼的OP。 – Cryptite

+0

@Cryptite:好的,我可能會得出結論。仔細查看你的帖子,還有更多問題。您不會在__init__中初始化killSwitch。你正在run()中訪問它。這應該給你一個AttributeError,但你用的是裸except子句捕獲所有異常並捕獲,然後這個錯誤通過。所以你的循環應該只運行一次。除了幾乎不是一個好主意。而在你的doFunction中,你正在檢查「完成」,但你正在發出「AllDone」。它真的*你正在使用的功能嗎?另外,我認爲你不需要run()中的return語句。 – Avaris

+0

我是我的,我確實擁有了所有這些東西,並且命名正確,但是我竟然混淆了代碼,導致我不小心誤導了代碼。我實際上是初始化init中的killSwitch,並且捕獲的是兩端的'done';並不意味着在那裏輸入AllDone。我想我剛剛在一個線程中看到了一個「返回」並正在嘗試,但是我肯定可以刪除它。原始代碼被更新併合並在一起,以便您可以更好地看到它;也放入了一些Qt的東西,所以它看起來更有意義。 – Cryptite