【问题标题】:How can I keep my gui responsive while making a Popen call?如何在拨打 Popen 电话时保持我的 gui 响应?
【发布时间】:2017-02-15 01:28:15
【问题描述】:

我正在尝试在调用 Popen 命令时播放一个 throbber(以动画追逐箭头 gif 的形式),但它不起作用,因为我认为在 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_())

【问题讨论】:

    标签: python python-2.7 pyqt pyqt4


    【解决方案1】:

    不要使用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")
    

    【讨论】:

    • 出色的答案!不知道为什么我不能对 Popen 做同样的事情,但这是一个完美的选择。
    • @answerSeeker,你可以用subprocess.Popen来做,但是需要另一个线程来等待子进程完成,比较麻烦。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    • 1970-01-01
    • 2017-12-21
    相关资源
    最近更新 更多