2014-02-05 52 views
2

PySide是新手,因此可能在這裏誤解了基礎知識。Python + QT:如何製作非GUI屏蔽加載屏幕?

我正在寫一個GUI應用程序,將啓動,然後執行各種系統檢查:

  • 檢查HW存在
  • 檢查網絡連接
  • 檢查API連接

在整個過程中,它會通知用戶它正在做什麼以及結果。

完成檢查(並通過) - 它們將進入程序初始屏幕。

目前,我一直試圖在定時器運行檢查,以QApplication.processEvents

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    rebadger = rebadger() 
    rebadger.initUI() 
    rebadger.show() 

    tT = QTimer() 
    tT.setSingleShot(False) 
    tT.timeout.connect(QApplication.processEvents) 
    tT.start(1000) 

    rebadger.rebadgeObj.runChecks() 

    sys.exit(app.exec_()) 

但一切仍阻止,直到檢查都做。

我已經在QThread文檔,但我發現它,而很難總結我周圍的事件邏輯頭(是否來自嚴格的PHP背景)

任何協助草擬的骨架如何實現這一點將不勝感激。

回答

1

這是你怎麼會做你想做的,檢查長期運行的後臺處理使用QThread是一個例子,作爲一個額外的你將有一個所以它適用於任何窗口不只是一個閃屏:

from PyQt4 import QtCore as core, QtGui as gui 
import time 

class MyProccess(core.QThread): 

    newProgress = core.pyqtSignal(str) 

    def __init__(self,i): 
     super(MyProccess,self).__init__() 
     self.id = i 

    def run(self): 
     for j in range(10): 
      self.newProgress.emit('task %d at %d%%' % (self.id,j*10)) 
      time.sleep(0.2)    


class MySplash(gui.QSplashScreen): 

    def __init__(self,mw): 
     super(MySplash,self).__init__() 
     layout = gui.QVBoxLayout(self) 
     self.setLayout(layout) 
     self.text = gui.QLabel(self) 
     layout.addWidget(self.text) 
     self.setGeometry(300,300,100,0)   

     self.task1 = MyProccess(1) 
     self.task2 = MyProccess(2) 
     self.task3 = MyProccess(3) 

     self.task1.newProgress.connect(self.showProgress) 
     self.task2.newProgress.connect(self.showProgress) 
     self.task3.newProgress.connect(self.showProgress) 

     self.task1.finished.connect(self.task2.start) 
     self.task2.finished.connect(self.task3.start) 
     self.task3.finished.connect(mw.show) 
     self.task3.finished.connect(self.hide) 

    @core.pyqtSlot(str) 
    def showProgress(self,msg): 
     self.text.setText(msg) 

    def event(self,ev): 
     if type(ev) == gui.QShowEvent: 
      self.task1.start() 
     return super(MySplash,self).event(ev) 

app = gui.QApplication([]) 

mw = gui.QMainWindow() 

cw = gui.QWidget() 
l = gui.QHBoxLayout() 
cw.setLayout(l) 
welcome = gui.QLabel() 
welcome.setText('Welcome back!') 
l.addWidget(welcome) 

mw.setCentralWidget(cw) 
mw.setGeometry(200,200,300,300) 


w = MySplash(mw) 
w.show() 

app.exec_() 
+0

這是完美的:進度從線程回傳,線程爲漸進/排序,GUI不是被阻止,並且生命可以在之後繼續。你能否稍微解釋一下** @ core.pyqtSlot(str)**參考嗎? – swx

+0

'MyProcess'包含一個未被使用的對標籤('self.out')的引用,它可能試圖使用它的 線程內的setText()方法。據我所知,這不應該做,所以這個變量沒有意義。 – TNT

+0

@TNT是的,你是對的,但我不使用它,也許它仍然是我的答案的早期版本,直到現在我還沒有意識到;)謝謝 –

4

也許QSplashScreen是你所需要的:

if __name__ == '__main__':                  

    import time                     
    app = QtGui.QApplication(sys.argv)               
    splash = QtGui.QSplashScreen(QtGui.QPixmap('splash.png'))          
    splash.show()                     
    for n in ("HW presence", "net connectivity", "API connectivity"):        
     splash.showMessage("Check for {0}".format(n))            
     time.sleep(1)                    
     app.processEvents()                  
    mainWin = MainWindow()                  
    splash.finish(mainWin)                  
    mainWin.show()                    
    sys.exit(app.exec_())                   
+0

您好TNT - 感謝您的答覆。我曾使用/試圖使用SplashScreen,但發現它不適合我想要的東西(IE,設計限於一個簡單的圖像,被點擊時關閉,當然,這並沒有解決問題,仍然需要processEvents ()被調用理論上,如果它應該用於splashScreen,它也可以用於任何其他常規形式嗎? – swx

+0

事實上,例如使用'mainWin',您可以在其中使用狀態欄作爲輸出,但也需要' processEvents()'。 – TNT

+0

但是,如果for循環中的任務需要很長時間才能處理,則GUI仍然會阻塞。 – swx