• 【Qt之QSplashScreen】开场动画使用:进度条加载及设置鼠标指针不转圈


    效果

    开场动画效果如下:

    开场动画

    介绍

    QSplashScreen小部件提供了一个启动屏幕,可以在应用程序启动期间显示。

    启动屏幕是一个小部件,通常在应用程序启动时显示。启动屏幕通常用于启动时间较长的应用程序(例如需要花费时间建立连接的数据库或网络应用程序),以便向用户提供应用程序正在加载的反馈。

    启动画面出现在屏幕中央。添加Qt::WindowStaysOnTopHintsplash小部件的窗口标志可能是有用的,如果你想让它在桌面上的所有其他窗口之上。

    一些X11窗口管理器不支持“停留在顶部”标志。一个解决方案是设置一个计时器,定期调用启动屏幕上的raise()来模拟“停留在顶部”的效果。

    最常见的用法是在主小部件显示在屏幕上之前显示一个闪屏。下面的代码片段说明了这一点,在显示应用程序的主窗口之前,会显示一个闪屏,并执行一些初始化任务:

      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
          // 添加像素图
          QPixmap pixmap(":/splash.png");
          QSplashScreen splash(pixmap);
          // 显示
          splash.show();
          app.processEvents();
          ...
          QMainWindow window;
          window.show();
          // 完成
          splash.finish(&window);
          // 事件循环
          return app.exec();
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    用户可以通过点击鼠标来隐藏闪屏。由于闪屏通常是在事件循环开始运行之前显示的,因此有必要定期调用QApplication::processEvents()来接收鼠标点击。

    有时用消息更新启动屏幕是有用的,例如,在应用程序启动时宣布连接建立或模块加载:

      QPixmap pixmap(":/splash.png");
      QSplashScreen *splash = new QSplashScreen(pixmap);
      splash->show();
    
      ... // Loading some items
      splash->showMessage("Loaded modules");
    
      qApp->processEvents();
    
      ... // Establishing connections
      splash->showMessage("Established connections");
    
      qApp->processEvents();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    QSplashScreen通过showMessage()函数支持这一点。如果你想自己绘图,你可以使用pixmap()获得一个指向启动屏幕中使用的像素图的指针。或者,你可以继承QSplashScreen并重新实现drawContents()

    使用场景

    QSplashScreen的使用场景包括但不限于以下几种情况:

    1. 启动时间较长的应用程序:对于启动时间较长、需要后台进行大量初始化的应用程序,QSplashScreen可以提供一个简单的启动画面,向用户展示应用程序正在加载,而不是让用户在空白或未响应的界面上等待。这有助于改善用户体验,让用户知道程序正在后台进行必要的准备工作。
    2. 需要显示加载进度的应用程序:如果应用程序在启动过程中需要进行大量数据处理或资源加载,QSplashScreen可以提供一个包含加载进度信息的界面。通过QSplashScreen的自定义功能,可以实时更新加载进度,让用户了解程序启动的进度情况。
    3. 需要展示程序名称、版本信息的应用程序QSplashScreen可以显示应用程序的名称和版本信息,这对于一些需要向用户展示程序基本信息的应用程序来说是非常有用的。通过在启动画面上显示这些信息,用户可以更直观地了解正在运行的应用程序的身份和版本。
    4. 需要实现渐变效果的应用程序QSplashScreen支持设置透明度和渐变效果,可以让启动画面在显示过程中逐渐淡入或淡出,增加视觉效果。这对于一些需要追求精美效果的应用程序来说是非常合适的。
    5. 需要进行连接数据库或网络的应用程序:对于需要连接数据库或网络的应用程序,QSplashScreen可以在连接过程中显示一些提示信息或进度条,让用户知道程序正在进行连接操作。这有助于改善用户体验,让用户知道应用程序正在执行特定的任务。

    总的来说,QSplashScreen的使用场景主要是那些需要在应用程序启动时提供视觉反馈、加载进度、基本信息展示以及需要实现渐变效果和连接数据库或网络的应用程序。通过使用QSplashScreen,这些应用程序可以在启动过程中提供更好的用户体验和视觉效果。

    方法

    1. QSplashScreen::QSplashScreen(const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags())
      构造一个显示 pixmap 的启动画面(Splash Screen)。
      除了可能使用 Qt::WindowStaysOnTopHint 标志外,通常不需要设置其他绘件标志。

    2. QSplashScreen::QSplashScreen(QWidget *parent, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags())
      这是一个重载函数。
      该函数允许您为启动画面指定一个父窗口。此构造函数的典型用途是当您拥有多个屏幕,并希望在启动画面上显示于主要屏幕不同的屏幕上。在这种情况下,将适当的 desktop() 作为父窗口传递进来。

    3. [virtual] QSplashScreen::~QSplashScreen()
      析构函数。

    4. [slot] void QSplashScreen::clearMessage()
      清除在启动画面上显示的消息。
      参见 showMessage()。

    5. [virtual protected] void QSplashScreen::drawContents(QPainter *painter)
      使用 painter 绘制启动画面的内容。默认实现会绘制 showMessage() 传递的消息。如果您想要在启动画面上进行自定义绘制,请重新实现此函数。

    6. [virtual protected] bool QSplashScreen::event(QEvent *e)
      从 QObject::event() 重新实现。

    7. void QSplashScreen::finish(QWidget *mainWin)
      使启动画面在显示 mainWin 窗口后再调用自己的 close() 函数。

    8. QString QSplashScreen::message() const
      返回当前在启动画面上显示的消息。

    9. [signal] void QSplashScreen::messageChanged(const QString &message)
      当启动画面上的消息发生变化时,发出此信号。message 是新消息,在消息被清除时为一个空字符串。

    10. [virtual protected] void QSplashScreen::mousePressEvent(QMouseEvent *)
      从 QWidget::mousePressEvent() 重新实现。

    11. const QPixmap QSplashScreen::pixmap() const
      返回用于显示启动画面的 pixmap。该图像不包含通过 showMessage() 绘制的任何文本。

    12. void QSplashScreen::repaint()
      此方法覆盖了 QWidget::repaint()。与标准的 repaint 函数不同,它还调用 QApplication::processEvents(),以确保更新的内容能够被显示,即使没有事件循环。

    13. void QSplashScreen::setPixmap(const QPixmap &pixmap)
      设置用作启动画面图像的 pixmap。

    14. [slot] void QSplashScreen::showMessage(const QString &message, int alignment = Qt::AlignLeft, const QColor &color = Qt::black)
      使用 color 颜色将消息文本绘制到启动画面上,并根据 alignment 中的标志对齐文本。此函数调用 repaint() 来确保启动画面立即更新。因此,消息可以根据应用程序的动作(例如,加载文件)及时更新。

    示例

    .h

    #ifndef CUSTOMSPLASHSCREEN_H
    #define CUSTOMSPLASHSCREEN_H
    
    #include 
    
    // 前置声明
    QT_FORWARD_DECLARE_CLASS(QProgressBar)
    
    /**
     * @brief The CustomSplashScreen class 自定义开场动画类
     */
    class CustomSplashScreen : public QSplashScreen
    {
        Q_OBJECT
    public:
        explicit CustomSplashScreen(QWidget *parent = nullptr);
    
        // 初始化
        void init();
    
    
    private:
        // 进度条
        QProgressBar*       m_pProgressBar;
    };
    
    #endif // CUSTOMSPLASHSCREEN_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    .cpp

    #include "customsplashscreen.h"
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define DELAYTIME 1000 // DELAYTIME为需要延时的毫秒数
    #define SHOWNO  3 // 显示加载次数
    
    CustomSplashScreen::CustomSplashScreen(QWidget *parent) : QSplashScreen(parent)
    {
        QString strScreen = "./ss.jpg";
    
        QFont font = this->font();
        font.setPixelSize(23);
        setFont(font);
    
        // 设置像素图
        QPixmap loadingPix(strScreen);
        setPixmap(loadingPix.scaled(500, 300));
    
        // 进度条
        m_pProgressBar = new QProgressBar(this);
        m_pProgressBar->setRange(0 ,100);
        m_pProgressBar->setValue(0);
        m_pProgressBar->setStyleSheet("QProgressBar{color:#ff0000;}");
    
        QLabel* pLabel = new QLabel("加载中...");
        pLabel->setStyleSheet("QLabel {color:#ff0000;  font-weight: bold;  font-style: italic;  font-size: 23px;}");
        QHBoxLayout* pHB = new QHBoxLayout();
        pHB->addStretch();
        pHB->addWidget(pLabel);
        pHB->addStretch();
    
        QVBoxLayout* pVB = new QVBoxLayout(this);
        pVB->addStretch();
        pVB->addLayout(pHB);
        pVB->addWidget(m_pProgressBar);
    
        this->setLayout(pVB);
    }
    
    void CustomSplashScreen::init()
    {
        // 先设置显示,再设置显示信息,如果设置完显示信息再设置显示,会看不到
        show();
    
        // 设置鼠标指针不转圈
        QApplication::setOverrideCursor(Qt::ArrowCursor);
    
        // 显示信息,及文本对齐方式:右上, 字体:red
        showMessage("程序正在加载...", Qt::AlignTop|Qt::AlignRight, Qt::red);
        QDateTime time = QDateTime::currentDateTime();
        QDateTime currentTime = QDateTime::currentDateTime(); // 记录当前时间
        m_pProgressBar->setValue(0);
        int nInter = time.msecsTo(currentTime);
        while(nInter <= DELAYTIME)
        {
            currentTime = QDateTime::currentDateTime();
            m_pProgressBar->setValue(0.025*nInter);
            nInter = time.msecsTo(currentTime);
        }
    
        for(int i = 0; i < SHOWNO; ++i)
        {
            showMessage(QString("请稍等%1...").arg(SHOWNO-i), Qt::AlignTop|Qt::AlignRight, Qt::red);
            time = currentTime;
            nInter = time.msecsTo(currentTime);
            while(nInter <= DELAYTIME)
            {
                currentTime = QDateTime::currentDateTime();
                m_pProgressBar->setValue(25*(i+1) + 0.025*nInter);
                nInter = time.msecsTo(currentTime);
            }
        }
        m_pProgressBar->setValue(100);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    main.cpp

    #include "mainwindow.h"
    #include 
    
    #include "customsplashscreen.h"
    
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        CustomSplashScreen ss;
        // 初始化
        ss.init();
    
        MainWindow w;
        w.show();
        // 动画结束
        ss.finish(&w);
    
        return a.exec();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    完整示例链接

    完整示例链接见文章最上方。

  • 相关阅读:
    【ASE入门学习】ASE入门系列九——软粒子与顶点着色
    【推搜】embedding评估 | faiss的topK向量检索
    力扣leetcode 最简单的中等题 2161. 根据给定数字划分数组
    Web应用的工作原理
    HP惠普暗影精灵9P OMEN 17.3英寸游戏本17-cm2000(70W98AV)原装出厂Windows11-22H2系统镜像
    从零开始的 dbt 入门教程 (dbt core 开发进阶篇)
    获取类中函数里面所有变量的变量名称
    如何与 TENNECO 建立 EDI 连接?
    深入剖析堆原理与堆排序
    Twins: Revisiting the Design of Spatial Attention in Vision Transformers
  • 原文地址:https://blog.csdn.net/MrHHHHHH/article/details/134447999