为啥 GUI 卡住并且后台进程运行良好?
Posted
技术标签:
【中文标题】为啥 GUI 卡住并且后台进程运行良好?【英文标题】:Why GUI is getting stucked and background process is running perfectly?为什么 GUI 卡住并且后台进程运行良好? 【发布时间】:2020-12-16 18:55:48 【问题描述】:我这样写一个程序:
cap = cv2.VideoCapture(video_path)
counter = 1
while True:
ret, frame = cap.read()
if not ret: break
cv2.imwrite(...)
self.progressbar.setValue(int((counter / self.totalFrame)*100))
time.sleep(1)
counter += 1
self.progressbar.setValue(0)
cap.release()
我想使用 opencv 从视频中提取所有帧,并希望在 PyQt5 进度条中显示进度。我还使用 sleep 来避免 Not Responding。但是程序显示我没有响应,进度条也被后台卡住了。工作做得很好。
如何正确显示进度条?
self.totalFrame 是视频的帧数。
进度条在 5 或 6 % 的进度后卡住 但是所有帧都被成功提取
【问题讨论】:
请提供minimal reproducible example @S.Nick 我已经发布了两个 ss。现在理解够了吗? 您正在使用 while 循环这一事实是导致 UI 无响应的主要原因,因为主 UI 线程中不应发生 阻塞。time.sleep()
也是如此,它的作用与您的想法完全相反:它阻止 UI 更新和响应。如果您需要一个连续处理某些内容的 parallel 函数,则需要为此使用一个单独的“worker” QThread,并带有一个为进度条发出值的自定义信号。做一些研究,因为即使在 *** 上也有很多关于这个主题的帖子。
@musicamante 好的!非常感谢!
不确定 PyQt 但在 C++ 中有一个函数可以从这样的循环中临时返回事件循环,以便执行/更新 gui 函数
【参考方案1】:
尝试将 time.sleep(1) 替换为 cv2.waitKey(1)
【讨论】:
但是另一个问题,在 cv2.waitKey(1) 之后,进度条有响应,但是当我尝试移动 GUI 时,它会在 1/2 秒后移动。【参考方案2】:今天我知道了如何在不实现 QThread 的情况下正确运行进度条。
我必须在声明后添加QApplication.processEvents()
。
cap = cv2.VideoCapture(video_path)
counter = 1
while True:
ret, frame = cap.read()
if not ret: break
cv2.imwrite(...)
self.progressbar.setValue(int((counter / self.totalFrame)*100))
QApplication.processEvents()
counter += 1
self.progressbar.setValue(0)
cap.release()
【讨论】:
以上是关于为啥 GUI 卡住并且后台进程运行良好?的主要内容,如果未能解决你的问题,请参考以下文章
Python Kivy:正确启动更新 GUI 元素的后台进程