【发布时间】:2020-09-20 13:16:51
【问题描述】:
开发人员!我有一个关于 Qt 和多线程的问题。
=== 简短版本 =========================================== =
可以用 Qt 做我想做的事吗?即(1)显示装载机; (2)在后台下载一个gif; (3) 下载好的gif在主窗口显示?
=== 长版 ============================================ ==
我有这样的想法,当我按下按钮时,它:
- 显示加载器;
- 激活从网络下载 gif 的线程;
- 将隐藏在主窗口中的默认gif替换为下载的gif并显示
- 隐藏加载器;
我遇到的问题是,当下载的 gif 被显示时,它被“冻结”或只显示第一帧。除此之外一切都很好。但是,它需要在加载器隐藏后动画 gif。
提到here那个
因此 Qt 事件循环负责执行代码以响应程序中发生的各种事情,但在执行代码时,它不能做任何其他事情。。 p>
我相信这是问题的核心。还建议
建议在 Qt 中使用 QThread 而不是 Python 线程,但是如果您不需要从函数与主线程回通信,Python 线程将可以正常工作。
由于我的线程替换了默认 gif 的内容,我相信 它确实会回传 :(
请在下面找到我的代码:)
import sys
from time import sleep
from PyQt5.QtCore import QThread
from PyQt5.QtGui import QMovie
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel
class ChangeGif(QThread):
"""
A worker that:
1 - waits for 1 second;
2 - changes the content of the default gif;
3 - shows the default gif with new contents and hide the loader.
"""
def __init__(self, all_widgets):
QThread.__init__(self)
self.all = all_widgets
def run(self):
sleep(1)
self.new_gif_file = QMovie("files/new.gif") # This is the "right" gif that freezes :(
self.new_gif_file.start()
self.all.gif_label.setMovie(self.new_gif_file)
self.all.gif_label.show()
self.all.loader_label.hide()
class MainWindow(QWidget):
"""
Main window that shows a button. If you push the button, the following happens:
1 - a loader is shown;
2 - a thread in background is started;
3 - the thread changes the contents of the default gif;
4 - when the gif is replaced, the loader disappears and the default gif with the new content is shown
"""
def __init__(self):
super(MainWindow, self).__init__()
# BUTTON
self.button = QPushButton("Push me", self)
self.button.setFixedSize(100, 50)
self.button.clicked.connect(lambda: self.change_gif())
# DEFAULT GIF
self.gif_file = QMovie("files/default.gif") # This is the "wrong" gif
self.gif_file.start()
self.gif_label = QLabel(self)
self.gif_label.setMovie(self.gif_file)
self.gif_label.move(self.button.width(), 0)
self.gif_label.hide()
# LOADER
self.loader_file = QMovie("files/loader.gif")
self.loader_file.start()
self.loader_label = QLabel(self)
self.loader_label.setMovie(self.loader_file)
self.loader_label.move(self.button.width(), 0)
self.loader_label.hide()
# WINDOW SETTINGS
self.setFixedSize(500, 500)
self.show()
def change_gif(self):
self.loader_label.show()
self.worker = ChangeGif(self)
self.worker.start()
app = QApplication(sys.argv)
window = MainWindow()
app.exec_()
【问题讨论】:
标签: python multithreading pyqt5 qthread qmovie