版权声明:本文为博主原创文章,未经博主允许不得转载。 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()