如何在打Popen电话时让我的gui响应?

如何在打Popen电话时让我的gui响应?

问题描述:

我试图在打电话给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_()) 

而不是使用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