gpt4 book ai didi

python PyQT : How to call a GUI function from a worker thread?

转载 作者:太空狗 更新时间:2023-10-30 02:45:23 25 4
gpt4 key购买 nike

我有一个 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()

然后将此 worker 移动到您创建的 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()

关于 python PyQT : How to call a GUI function from a worker thread?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24820063/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com