给程序加一个炫酷的启动界面

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/this_is_id/article/details/88681276

一、静态图片

使用pyqt自带的QSplashScreen类实现,比较简单,如要实现不规则的启动界面,可将jpg图片换成png透明图片即可,源码如下:

import time

from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QFont
from PyQt5.QtWidgets import QMainWindow, QSplashScreen


class Form(QMainWindow):
    def __init__(self, splash):
        super(Form, self).__init__()
        self.resize(800, 600)

        self.splash = splash

        self.load_data()

    def load_data(self):
        for i in range(10):
            time.sleep(1)
            self.splash.showMessage(f'加载中...{str(i * 10)}%', Qt.AlignLeft | Qt.AlignBottom, Qt.white)


if __name__ == '__main__':
    import sys
    from PyQt5.QtWidgets import QApplication

    app = QApplication(sys.argv)

    splash = QSplashScreen()
    splash.setPixmap(QPixmap(r'D:\图标\28c932975ab836b2d1939979db0fd8b8.jpg'))  # 设置背景图片
    splash.setFont(QFont('微软雅黑', 10))  # 设置字体
    splash.show()
    app.processEvents()  # 处理主进程,不卡顿
    form = Form(splash)
    form.show()
    splash.finish(form)  # 主界面加载完成后隐藏
    splash.deleteLater()
    app.exec_()

截图

二、动态图片

前面实现的启动界面会有一个小问题,当鼠标点击启动界面时候,启动界面会被隐藏掉,解决方法:继承QSplashScreen,重写mousePressEvent即可解决。

为了保证动画的流畅加载,因此需要把load_data部分的工作移到线程中,由主界面来启动线程,线程启动后,为了确保线程完成前不断刷新启动界面,加入如下代码:

while self.load_thread.isRunning():
    QtWidgets.qApp.processEvents()

尽管如此,在线程启动时,界面还会有一点卡顿,暂时不知道怎么解决,源码如下:

import time

from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt, QObject, QThread, pyqtSignal
from PyQt5.QtGui import QFont, QMovie
from PyQt5.QtWidgets import QMainWindow, QSplashScreen


class MySplashScreen(QSplashScreen):
    def __init__(self):
        super(MySplashScreen, self).__init__()

        # 新建动画
        self.movie = QMovie(r'D:\图标\51b56964552b765c919f5a1cf386f140.gif')
        self.movie.frameChanged.connect(lambda: self.setPixmap(self.movie.currentPixmap()))
        self.movie.start()

    def mousePressEvent(self, QMouseEvent):
        pass


class LoadDataWorker(QObject):
    finished = pyqtSignal()
    message_signal = pyqtSignal(str)

    def __init__(self):
        super(LoadDataWorker, self).__init__()

    def run(self):
        for i in range(10):
            time.sleep(1)
            self.message_signal.emit(f'加载中...{str(i * 10)}%')
        self.finished.emit()


class Form(QMainWindow):
    def __init__(self, splash):
        super(Form, self).__init__()
        self.resize(800, 600)

        self.splash = splash

        self.load_thread = QThread()
        self.load_worker = LoadDataWorker()
        self.load_worker.moveToThread(self.load_thread)
        self.load_thread.started.connect(self.load_worker.run)
        self.load_worker.message_signal.connect(self.set_message)
        self.load_worker.finished.connect(self.load_worker_finished)
        self.load_thread.start()

        while self.load_thread.isRunning():
            QtWidgets.qApp.processEvents()  # 不断刷新,保证动画流畅

        self.load_thread.deleteLater()

    def load_worker_finished(self):
        self.load_thread.quit()
        self.load_thread.wait()

    def set_message(self, message):
        self.splash.showMessage(message, Qt.AlignLeft | Qt.AlignBottom, Qt.white)


if __name__ == '__main__':
    import sys
    from PyQt5.QtWidgets import QApplication

    app = QApplication(sys.argv)

    splash = MySplashScreen()
    # splash.setPixmap(QPixmap(r'D:\图标\28c932975ab836b2d1939979db0fd8b8.jpg'))  # 设置背景图片
    splash.setFont(QFont('微软雅黑', 10))  # 设置字体
    splash.show()

    app.processEvents()  # 处理主进程,不卡顿
    form = Form(splash)
    form.show()
    splash.finish(form)  # 主界面加载完成后隐藏
    splash.movie.stop()  # 停止动画
    splash.deleteLater()
    app.exec_()

截图

三、炫酷启动界面

可以重写QSplashScreen的paintEvent事件,来实现一些炫酷的动画,动画的核心算法是在github上找到的(大神链接),paintEvent代码如下:

    def paintEvent(self, event):
        super(NewSplashScreen, self).paintEvent(event)
        painter = QPainter()
        painter.begin(self)
        painter.setRenderHint(QPainter.Antialiasing)
        # painter.drawImage(QRectF(0, 0, self.width(), self.height()), QImage(self.picture))
        painter.save()
        painter.setPen(QColor(255, 255, 255))
        painter.drawText(QPoint(5, self.height() - 8), self.message)
        painter.restore()
        # painter.fillRect(self.rect(), Qt.black)
        self.animate(painter)
        painter.end()

截图

猜你喜欢

转载自blog.csdn.net/this_is_id/article/details/88681276