我有一个 pyqt gui 并调用一个长进程(ffmpeg),我将其放在一个单独的线程上以不阻塞 gui。然后,我想在较长命令列表中的一个命令完成时更新进度栏。问题是,我无法在工作线程之外调用 gui 线程中的函数。所以我让在工作线程中运行一个股票代码,但是当我用 while 循环更新进度条并读取股票代码值时,GUI 再次被阻止。我该如何解决这个问题。我当前使用的是 python 线程而不是 Qthread。
感谢您的帮助!
import threading, pexpect
self.cmd_list = ['ffmpeg -i file outfile','and so on']
self.stop_proc = False
self.executeCMD()
def spawn_ffmpeg_cmd(self):
for cmd in self.cmd_list:
if self.stop_proc == False:
thread = pexpect.spawn(cmd)
print "\nstarted: %s" % cmd
cpl = thread.compile_pattern_list([pexpect.EOF,"frame= *\d+ fps=*\d+",'(.+)'])
while True:
i = thread.expect_list(cpl, timeout=None)
if i == 0: # EOF
print "the sub process exited"
self.pgticker += 1
break
elif i == 1:
frame_number_fps = thread.match.group(0)
print frame_number_fps
thread.close
elif i == 2:
pass
self.startButton.setEnabled(True)
def executeCMD(self):
self.startButton.setEnabled(False)
self.pgticker = 0
threading.Thread(target=self.spawn_ffmpeg_cmd, name="_proc").start()
def stopprocess(self):
self.stop_proc = True
self.cmd_list = []
os.system('pkill ffmpeg')
self.pgticker = len(self.cmd_list)
self.startButton.setEnabled(True)
def updateProgress(self):
pgfactor = 100 / len(self.cmd_list)
progress = 0.0
progress = pgfactor*int(self.pgticker)
self.progressBar.setProperty("value", progress)
简而言之:移至QThread
并使用Qt的信号和槽,它们是线程之间通信的首选方式。
这个答案提供了一些示例:https://stackoverflow.com/a/6789205/2319400
在您的情况下,使用上面的“SomeObject”版本可能如下所示:
class Worker(QtCore.QObject):
madeProgress = QtCore.pyqtSignal([int])
finished = QtCore.pyqtSignal()
def __init__(self, cmdlist):
self.cmdlist = cmdlist
def run(self):
for icmd, cmd in enumerate(self.cmdlist):
# execute your work
# processCommand(cmd)
# signal that we've made progress
self.madeProgress.emit(icmd)
# emit the finished signal - we're done
self.finished.emit()
然后将此工人移至QThread
您创建的实例。
按照链接答案中的模式,您可以连接madeProgress
信号
到setValue
进度条的插槽:
workerThread = QThread()
workerObject = Worker(cmdlist)
workerObject.moveToThread(workerThread)
workerThread.started.connect(workerObject.run)
workerObject.finished.connect(workerThread.quit)
# create a progressbar with min/max according to
# the length of your cmdlist
progressBar = QProgressBar()
progressBar.setRange(0, len(cmdlist))
# connect the worker's progress signal with the progressbar
workerObject.madeProgress.connect(progressBar.setValue)
# start the thread (starting your worker at the same time)
workerThread.start()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)