2017-02-15 22 views
1

Я пытаюсь иметь тибетский (в виде анимированных стрелок giz ging), играя, когда я вызываю команду Popen, но это не работает, потому что я думаю, что gui полностью не отвечает, когда команда Popen запущена. Как я могу это исправить? Пожалуйста, проверьте мой код ниже.Как я могу сохранить отзывчивость во время вызова Popen?

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

Splendid ответ! Не знаю, почему я не могу сделать то же самое с Попеном, но это идеальная альтернатива. – answerSeeker

+0

@answerSeeker, вы можете сделать это с помощью 'subprocess.Popen', но для этого требуется еще один поток, чтобы подождать завершения подпроцесса, что является громоздким. – falsetru