2017-02-15 74 views
1

我試圖在打電話給Popen命令的同時打一個throbber(形式爲動畫追逐箭頭gif),但它不起作用,因爲我認爲gui在Popen命令運行時完全沒有響應。我怎樣才能解決這個問題? 請檢查我的代碼如下。如何在打Popen電話時讓我的gui響應?

import subprocess 
import os 
import sys 
from PyQt4 import QtCore, QtGui 

class Test(QtGui.QDialog): 

    def __init__(self, parent=None): 
     super(Test, self).__init__(parent) 
     self.setMinimumSize(200, 200) 
     self.buttonUpdate = QtGui.QPushButton() 
     self.buttonUpdate.setText("Get updates") 
     self.lbl1 = QtGui.QLabel() 
     self.lbl2 = QtGui.QLabel() 
     self.lblm2 = QtGui.QLabel() 

     gif = os.path.abspath("chassingarrows.gif")#throbber 
     self.movie = QtGui.QMovie(gif) 
     self.movie.setScaledSize(QtCore.QSize(20, 20)) 

     self.pixmap = QtGui.QPixmap("checkmark.png")#green checkmark 
     self.pixmap2 = self.pixmap.scaled(20, 20) 

     verticalLayout = QtGui.QVBoxLayout(self) 
     h2 = QtGui.QHBoxLayout() 
     h2.addWidget(self.lblm2) 
     h2.addWidget(self.lbl2) 

     h2.setAlignment(QtCore.Qt.AlignCenter) 

     verticalLayout.addWidget(self.lbl1) 
     verticalLayout.addLayout(h2) 
     verticalLayout.addWidget(self.buttonUpdate, 0, QtCore.Qt.AlignRight) 
     self.buttonUpdate.clicked.connect(self.get_updates) 

    def get_updates(self): 
     try: 
      self.lbl1.setText("Updating") 
      self.lblm2.setMovie(self.movie) 
      self.movie.start() 
      self.setCursor(QtCore.Qt.BusyCursor) 
      p1 = subprocess.Popen(['apt', 'update'], stdout=subprocess.PIPE, bufsize=1) 
      p1.wait() 
      self.movie.stop() 
      self.lblm2.setPixmap(self.pixmap2) 
      self.unsetCursor() 
      self.lbl1.setText("Done update") 
     except subprocess.CalledProcessError, e: 
      print e.output 

if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    test = Test() 
    test.show() 
    sys.exit(app.exec_()) 

回答

2

而不是使用subprocess.Popen的,使用QProcess允許回調時過程中使用finished信號完成:

def get_updates(self): 
    self.lbl1.setText("Updating") 
    self.lblm2.setMovie(self.movie) 
    self.movie.start() 
    self.setCursor(QtCore.Qt.BusyCursor) 

    self.p1 = QProcess() 
    self.p1.finished.connect(self.on_apt_update_finished) 
    self.p1.start('apt', ['update']) 

def on_apt_update_finished(self, exit_code, exit_status): 
    self.movie.stop() 
    self.lblm2.setPixmap(self.pixmap2) 
    self.unsetCursor() 
    self.lbl1.setText("Done update") 
+0

輝煌的答案!不知道爲什麼我不能和Popen做同樣的事情,但這是一個完美的選擇。 – answerSeeker

+0

@answerSeeker,你可以用'subprocess.Popen'來完成,但它需要另一個線程來等待子進程完成,這很麻煩。 – falsetru

相關問題