2017-02-15 3 views
1

Ich versuche einen Throbber (in Form eines animierten Jagdpfeils gif) spielen zu lassen, während ich einen Popen-Befehl anrufe, aber es funktioniert nicht, weil ich glaube, dass die GUI nicht reagiert, während der Popen-Befehl ausgeführt wird. Wie kann ich das beheben? Bitte überprüfen Sie meinen Code unten.Wie kann ich während eines Popen-Anrufs meine Antwort halten?

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_()) 

Antwort

2

Statt subprocess.Popen zu verwenden, verwenden QProcess, dem Rückruf erlauben, wenn der Prozess finished Signal unter Verwendung beendet:

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

Splendid Antwort! Ich weiß nicht, warum ich das nicht mit Popen machen kann, aber das ist eine perfekte Alternative. – answerSeeker

+0

@answerSeeker, Sie können es mit 'subprocess.Popen' machen, aber es erfordert einen anderen Thread, um den Abschluss des Unterprozesses zu warten, was umständlich ist. – falsetru

Verwandte Themen