2015-05-19 41 views
0

我已經用Python的線程模塊做了例程來運行一個子進程並等待它完成。 我做穿線用下面一行:從一個線程啓動一個函數。 (GUI線程和QThread錯誤)

t1=Thread(target=self.routineFunction, args=(self, "file1.txt", "file2.txt", self.nextFunction)).start() 

在我的功能routineFunction(自我,文件1,文件2,nextFunction)我叫下一個功能,一旦子進程運行完畢後才能運行。

一切工作正常,直到那時。

但是如果我在我的下一個函數來創建新的QObject的項目,我收到了很多的錯誤: - 「的QPixmap:這不是安全使用GUI線程之外的像素圖」 - 「的QObject :: startTimer所:QTimer能只能使用線程開始的QThread」

我的猜測是,當我打電話nextFunction從常規它在同一個線程的程序中,因此錯誤的跑了。 有沒有辦法從「main」或「normal」線程中的例程調用一個函數?

謝謝你的幫助。

+0

使用qt線程代替python線程,並在worker完成時發出信號。 – ekhumoro

回答

2

一般來說,它是好的從其他線程調用函數。但是許多GUI庫(QT就在其中)對這種行爲有一些限制。

例如,有一個叫做'GUI線程'的指定線程,它處理所有圖形的東西,比如從OS調度消息,重繪窗口等。而且你也限制使用這個唯一線程來處理GUI。因此,例如,您不應在其他線程中創建QPixmap

QTimer使用一些QThread的內部數據,所以你應該使用只在開始QThread螺紋,定時器,但與普通的Python thread模塊。

回到你的問題,如果你想使用QT工作,你應該使用QThread產生你的線程,並使用postEvent()方法將事件發佈到GUI線程。這將保證QT內部數據結構的一致性。因此,你可以在任何QT線程中運行你的代碼,但是如果你想使用GUI(你的QObject使用QPixmap,所以情況是這樣),你只需要在GUI線程中處理這種調用。

+0

感謝您的好解釋。我將嘗試使用此QThread和postEvent()返回到GUI線程 –

0

好了,所以我認爲werewindle的解決方案是可能的。不幸的是,我發現很難將當前的腳本從Thread轉換爲QThread(我通常是新線程)。

我找到了一個解決方法: 而不是傳遞nextFunction作爲參數,我傳遞隊列= Queue.Queue()和我使用queue.put(True)如果我的新線程中的子進程是成功的。沒有更多的nextFunction,我只需使用queue.get()等待隊列中的值。 通過這樣做,我可以繼續在GUI線程中。