2011-04-10 96 views
1

我正在尝试使用PyQt为名为“HandBrake”的视频转换器应用程序构建一个简单的GUI。子进程Popen阻止PyQt图形用户界面

我的问题是,当我选择一个视频文件进行转换时,子进程Popen用必要的参数启动手刹应用程序,但在等待手刹结束时,gui被阻止,因此我无法做任何更改。 (例如:我不能禁用pushButton,也不能更改它的文本)

我不是在寻找更复杂的解决方案,例如进度条等,但我只想简单地禁用按钮并在等待时更改其文本为程序完成转换。

我该怎么用python & pyqt做这种事?

def videoProcess(): 
    self.pushButton.setEnabled(0) 
    self.pushButton.setText("Please Wait") 
    command = "handbrake.exe -i somefile.wmv -o somefile.mp4" 
    p = subprocess.Popen(str(command), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
    while 1: 
     line = p.stdout.readline() 
     if not line: 
      self.pushButton.setEnabled(1) 
      break 
+1

使用一个单独的线程或使用'multiprocessing'。 – 2011-04-10 18:50:00

回答

10

既然你在Qt的土地已经你可以做这样的事情:

from PyQt4.QtCore import QProcess 

class YourClass(QObject): 

    [...] 

    def videoProcess(self): 
     self.pushButton.setEnabled(0) 
     self.pushButton.setText("Please Wait") 
     command = "handbrake.exe" 
     args = ["-i", "somefile.wmv", "-o", "somefile.mp4"] 
     process = QProcess(self) 
     process.finished.connect(self.onFinished) 
     process.startDetached(command, args) 

    def onFinished(self, exitCode, exitStatus): 
     self.pushButton.setEnabled(True) 

    [...] 

http://doc.qt.io/qt-5/qprocess.html

1

如果你不关心输出无论如何,你可以使用p.wait()等待subproc完成,但你仍然需要控制返回到QT主循环,所以你需要以某种方式插入线程。最简单的解决方案将是这样的:

import threading 
def reenable(): 
    p.wait() 
    self.pushButton.setEnabled(1) 
t = threading.Thread(reenable) 
t.run() 

有这许多未解决的问题。例如,是否允许从多个线程调用GUI操作?怎么样超时?但它应该足以让你指向正确的方向。

+0

谢谢你的回答,但我想我忘记提及,我可以重新启用按钮后,但我不能禁用它在开始,虽然我打电话“self.pushButton.setEnabled(0)”功能在popen之前。 – eymen 2011-04-10 19:11:05