I'm trying to build a simple gui for a video converter application called "HandBrake" using PyQt.
My problem is that when I choose a video file to convert, subprocess Popen starts handbrake application with the necessary args but while waiting for handbrake to finish the gui gets blocked so I can't do any changes. (Ex: I can't disable the pushButton nor change its text)
I'm not looking for a more complicated solution such as progressbar etc. but I'd like to simply disable the button and change its text while waiting for the program to finish converting.
How can I do such thing with 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
Since you are in Qt land already you could do something like this:
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
If you don't care about the output anyway, you can use p.wait() to wait for the subproc to finish, but you still need to return control to the QT main loop, so you need to insert a thread somehow. The simplest solution would be something like:
import threading
def reenable():
p.wait()
self.pushButton.setEnabled(1)
t = threading.Thread(reenable)
t.run()
There are numerous unresolved issues with this. For example, is it permissible to call GUI actions from multiple thread? What about a timeout? But it should be enough to point you in the right direction.