首页 > 解决方案 > 如何在不阻塞 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)

标签: pythonpython-3.xuser-interfacepyqtpyqt5

解决方案


好吧,因为你没有发布任何最小的例子,所以我创建了一个,它工作正常,没有阻塞主要功能,加载 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_())


推荐阅读