python - 如何在不阻塞 PyQt 主程序的情况下制作弹出窗口?
问题描述
我正在开发一个基于 pyqt5 的 GUI python 程序。当我按下计算程序开始计算时,我想让用户知道它正在计算。我尝试在计算开始时使用 .gif 动画制作 QDialog,并在计算结束时关闭它。我遇到了一个问题,我要么得到没有 .gif 动画的空白窗口,要么动画开始但它阻塞了主窗口。我也试过 QThread 但没有运气。我发现 QDialog 完全阻止了您的应用程序执行。你能帮我解决这个问题吗?谢谢您的反馈!
这是动画对话框类的代码,其中主程序执行但 .gif 动画不显示:
class LoadingScreen:
"""Loading screen animation."""
def __init__(self, gif_path):
self.dlg = QDialog()
self.dlg.setWindowTitle("Loading")
self.dlg.setWindowModality(False)
self.dlg.setFixedSize(200, 200)
self.dlg.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.CustomizeWindowHint)
self.label_animation = QLabel(self.dlg)
self.movie = QMovie(gif_path)
self.label_animation.setMovie(self.movie)
def start_animation(self):
self.movie.start()
self.dlg.show()
def stop_animation(self):
self.movie.stop()
self.dlg.done(0)
解决方案
好吧,因为你没有发布任何最小的例子,所以我创建了一个,它工作正常,没有阻塞主要功能,加载 gif 并在按钮按下时播放。
import sys
from PyQt5.QtWidgets import QApplication, QDialog, QLabel, QMainWindow, QPushButton
from PyQt5.QtGui import QMovie
from PyQt5.QtCore import Qt, QSize
class LoadingScreen:
"""Loading screen animation."""
def __init__(self, gif_path):
self.dlg = QDialog()
self.dlg.setWindowTitle("Loading")
self.dlg.setWindowModality(False)
self.dlg.setFixedSize(350, 350)
self.dlg.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.CustomizeWindowHint)
self.label_animation = QLabel(self.dlg)
self.movie = QMovie(gif_path)
self.movie.setScaledSize(QSize(self.dlg.width(), self.dlg.height()))
self.label_animation.setMovie(self.movie)
def start_animation(self):
self.movie.start()
self.dlg.show()
def stop_animation(self):
self.movie.stop()
self.dlg.done(0)
class AppWindow(QMainWindow):
def __init__(self):
super(AppWindow, self).__init__()
self.pushButton_load = QPushButton("Press to \nLoad animation",self)
self.pushButton_load.setFixedSize(150,50)
self.pushButton_load.move(50, 50)
self.setFixedSize(300,150)
self.pushButton_load.clicked.connect(self.load_animation)
self.animation_started = False
def load_animation(self):
if not self.animation_started:
self.animation_started = True
self.pushButton_load.setText("Press to \nStop animation")
gif_path = "funny.gif" # path to the gif file you want to load
self.loading_screen = LoadingScreen(gif_path)
self.loading_screen.start_animation()
else:
self.animation_started = False
self.pushButton_load.setText("Press to \nLoad animation")
self.loading_screen.stop_animation()
def closeEvent(self, a0) -> None: # declare the close event to close the created window with the main application close
try:
self.loading_screen.stop_animation()
except AttributeError:
pass
self.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
w = AppWindow()
w.show()
sys.exit(app.exec_())
推荐阅读
- wpf - 如何在 wpf 中制作圆形和空白按钮
- kotlin - 列表
> 到可计算的未来 - >
- django - Django Rest Framework has_object_permission 未返回指定的“消息”
- python - “Pip install”导致“错误:命令‘gcc’失败,退出状态为 1”
- javascript - 在处理路由请求的同时运行间隔函数 NodeJS
- python - selenium.common.exceptions.InvalidArgumentException:消息:无效参数:使用 Selenium Python 上传文件时找不到文件错误
- python - TypeError:文件必须具有“read”和“readline”属性
- android - 如何对使用上下文的类进行单元测试?
- c++ - 在 switch 语句中同步调用 C++ std::async
- sql-server - CTE 执行多次