编辑
2025-03-03
工作知识
0
请注意,本文编写于 95 天前,最后修改于 95 天前,其中某些信息可能已经过时。

目录

一:重写QSplashScreen
二:初始化splash
三:销毁SplashScreen
四:让动画继续播放
五:如何调用动画
总结:

一:重写QSplashScreen

#include <QSplashScreen> #include <QMouseEvent> class AppSplashScreen : public QSplashScreen { Q_OBJECT public: explicit AppSplashScreen(QPixmap pixmap); ~AppSplashScreen(); void mousePressEvent(QMouseEvent *event); }; AppSplashScreen::AppSplashScreen(QPixmap pixmap) : QSplashScreen(pixmap) { this->setAttribute(Qt::WA_TransparentForMouseEvents, false); this->setWindowFlags(Qt::FramelessWindowHint); this->setAttribute(Qt::WA_TranslucentBackground); } /* 重写mousePressEvent */ void AppSplashScreen::mousePressEvent(QMouseEvent *event) { return; } AppSplashScreen::~AppSplashScreen() { }
  1. 重写mousePressEvent 为了屏蔽鼠标点击事件
  2. 设置窗口属性:
  this->setAttribute(Qt::WA_TransparentForMouseEvents, false); 设置禁止鼠标事件到父窗口   this->setWindowFlags(Qt::FramelessWindowHint); 设置窗口无边框   this->setAttribute(Qt::WA_TranslucentBackground); 设置窗口透明

二:初始化splash

/** * @brief 在应用启动过程中附上gif作为开启动画 */ void MainWindow::InitSplash(void) { int width,height; setFixedSize(800, 460); splash = new AppSplashScreen(QPixmap(":/png/png/splash.gif").scaled(width, height)); label = new QLabel(splash); mv = new QMovie(":/png/png/splash.gif"); bool istablet = QGSettings("org.ukui.SettingsDaemon.plugins.tablet-mode").get("tablet-mode").toBool(); if(istablet == true){ width = QGuiApplication::primaryScreen()->geometry().width(); height = QGuiApplication::primaryScreen()->geometry().height(); }else{ width = this->width(); height = this->height(); } splash->setFixedSize(width,height); label->setFixedSize(QSize(width , height)); mv->setScaledSize(label->size()); QScreen *screen = QGuiApplication::primaryScreen(); splash->move((screen->geometry().width() - width) / 2,(screen->geometry().height() - height) / 2); splash->showMessage(QObject::tr("正在启动程序..."), Qt::AlignRight | Qt::AlignTop, Qt::white); label->setMovie(mv); mv->start(); if(istablet == true){ splash->showFullScreen(); }else{ splash->show(); } for(int i=0; i<100; i++) { qApp->processEvents(); QThread::msleep(1); } }
  • setFixedSize 设置了父窗体的最大大小和最小大小为 800,460 它相当于设置了setMinimumSize和setMaximumSize都为同一个值
  • setScaledSize 将图片缩放大小设置为固定size。也就是这个QLabel的fixedsize
  • 为了与应用程序保持一致的位置,需要和应用程序一样,将splash移动到屏幕中间
  QScreen *screen = QGuiApplication::primaryScreen();   splash->move((screen->geometry().width() - width) / 2,(screen->geometry().height() - height) / 2);
  • showMessage 在splash播放的时候,显示文本信息
  • 绑定QMovie到QLabel上,并且开始播放gif
  label->setMovie(mv);   mv->start();
  • qApp->processEvents();代表当前的事情不重要,其他线程任务仍继续进行。用于不断刷新splash的事件,从而正常播放gif动画这里故意循环了100次,msleep1,也就意味着,当前至少100ms用于播放动画。然后再继续处理其他事情
  • 综合上面代码,initsplash过程中,初始化和播放了一个gif,并且让他默认走了100ms。

三:销毁SplashScreen

/** * @brief 销毁new出来的 QMovie QLabel AppSplashScreen */ void MainWindow::DestorySplash(void) { splash->finish(this); delete mv; mv = NULL; delete label; label = NULL; delete splash; splash = NULL; }

四:让动画继续播放

/** * @brief 不断设置动画消息 */ void MainWindow::SplashShowmsg(const QString msg) { label->setMovie(mv); mv->start(); Qt::Alignment topRight = Qt::AlignRight | Qt::AlignTop; splash->showMessage(msg,topRight, Qt::white); for(int i=0;i<10;i++) { qApp->processEvents(); splash->repaint(); } }

五:如何调用动画

MainWindow::MainWindow(QStringList str,QWidget *parent) :QWidget(parent) { mainWid = new QWidget(); InitSplash(); /* 主界面做其他事情 */ mainWid->show(); DestorySplash(); }

总结:

上面描述了如何设置一个QSplashScreen,从而让你的程序开启时出现动画效果。但对于效率来说,它为了绘制动画做了很多不必要的sleep和repaint/show。