2014-12-05 167 views
3

我有一個python控制檯腳本,我想添加一個基本的狀態窗口,所以在不知道pyqt的情況下我添加了一個窗口。如果我從主線程啓動pyqt,則會阻塞其他所有內容,所以我從另一個線程啓動它。它幾個月來一直運行良好,但我只是注意到了一個警告(不知道我是如何錯過它): WARNING: QApplication was not created in the main() thread.我想知道這可能會導致什麼問題。從python線程(不是主線程)啓動pyQt線程有什麼不好?

這是我使用的代碼的簡化版本,只是更新窗口的標題欄中:

from PyQt4 import QtGui, QtCore 
import threading 
import sys 
from time import sleep 

class MainWidget(QtGui.QWidget): 
    def __init__(self, parent=None): 
     super(MainWidget, self).__init__(parent) 
     self.setWindowTitle(statusLine) 
     self.timer = QtCore.QBasicTimer() 
     self.timer.start(500, self) 


    def updateWindow(self): 
     self.setWindowTitle(statusLine) 


    def timerEvent(self, event): 
     if event.timerId() == self.timer.timerId(): 
      self.updateWindow() 
     else: 
      super(MainWidget, self).timerEvent(event) 


def startWindow(): 
    app = QtGui.QApplication(sys.argv) 
    mw = MainWidget() 
    mw.show() 
    app.exec_() 


if __name__ == '__main__': 
    global statusLine 
    statusLine = 'foo' 
    threadWindow = threading.Thread(target=startWindow) 
    threadWindow.start() 
    sleep(2) # process lots of data 
    statusLine = 'bar' 
    # keep doing stuff and updating statusLine 

編輯:它看起來像我不明白這個簡單的示例警告;相反,如果我在啓動pyQt之前啓動多個其他python線程,我似乎只得到它。然而問題仍然存在:這樣做有什麼問題?

回答

4

我要說的是,因爲用戶與GUI交互存在一定危險,人們殺死沒有實際殺害主程序界面,這可能會導致:

  1. 問題,因爲另一個實例被啓動,導致資源泄漏,衝突等&
  2. 問題,因爲__main__試圖更新不再存在的GUI。

它似乎被普遍認爲帶有GUI程序的最佳實踐,QT或WX,是否有GUI爲__main__和有孩子線程做任何的背景下,密集計算,處理。當然,在OnExit方法中顯式地終止任何子線程仍然是一個好主意。

+0

謝謝。因此,對於我的情況,我只是將一個簡單的gui當作事後補充,但是從線程調用pyQt會直接破壞任何東西,這不僅僅是因爲它管理起來不夠優雅。爲了最佳實踐(如果我要重新開始),我絕對可以看到以不同的方式做。現在我已經確定關閉GUI也會觸發主線程正常關閉,而main並不直接對GUI執行任何操作,而是更新全局變量(這當然是可怕的練習,我是當然)gui讀取一個計時器。 – fantabolous 2014-12-05 13:13:40

+0

而不是在GUI上用螺栓固定,它幾乎和掀起前端/包裝一樣快。 – 2014-12-05 13:19:45

+0

嗯,這是一個想法。但是我知道pyQt使用自己的線程風格,所以我擔心重新編寫原始的多線程代碼以便在Qt下工作將是一項相當大的任務。或者是否有一個把它插入Qt的技巧? – fantabolous 2014-12-05 13:38:21