当前位置: 代码迷 >> 综合 >> 【Qt】如何做出炫酷的启动界面(GIF+ProgressBar)
  详细解决方案

【Qt】如何做出炫酷的启动界面(GIF+ProgressBar)

热度:64   发布时间:2023-12-13 20:46:01.0

一款高大上的应用程序怎么可以少得了拥有一个炫酷的开场秀?
先看效果图:
在这里插入图片描述
一般使用Qt来实现启动界面的方法很简单,只需要在main函数里面使用Qt自带的类QSplashScreen,然后传进去一个QPixmap对象即可。
官方给出的方法:

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();}

使用这段代码千万不要直接粘贴,因为坑的一点是,主窗口使用的对象类是QMainWindow,把我坑惨了。。一定要改成自己的主窗口的类呀。
如果不出什么差错的话,只使用官方给出的这段代码,启动图片会一闪而过,你根本都还没看到就闪没了。
想要真正达到一个可以观看的效果还是要在启动图像出现的时候执行一些操作,比如有的老师讲到这的时候会让程序执行循环:100000000000次的for循环,当然你电脑性能够好的话还是一闪而过,这样肯定是不行的。
下一个方法就是使用延时,控制时间,间接让启动图片展示6秒钟。

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);QPixmap pixmap(":/img/lixian.jpg");QSplashScreen splash(pixmap);splash.show();splash.setCursor(Qt::BlankCursor);app.processEvents();QDateTime n=QDateTime::currentDateTime();QDateTime now;do{
    now=QDateTime::currentDateTime();} while (n.secsTo(now)<=5);//6为需要延时的秒数MainWindow window;window.show();splash.finish(&window);return app.exec();

代码同样很好理解,这样就会使得pixmap显示6秒钟,然后进入MainWindow。
静态的还是不够高大上啊!能不能使用动态的呢?
可以使用GIF图像来进行播放,主要思路是使用QLabel和QMovie,
在这里插入图片描述
看代码:

#include "unistd.h" //usleep()
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);QPixmap pixmap(":/img/start_logo.gif");QSplashScreen splash(pixmap);QLabel label(&splash);QMovie mv(":/img/start_logo.gif");label.setMovie(&mv);mv.start();splash.show();splash.setCursor(Qt::BlankCursor);for(int i=0; i<5000; i+=mv.speed()){
    QCoreApplication::processEvents();usleep(500*static_cast<__useconds_t>(mv.speed()));}MainWindow window;window.show();splash.finish(&window);return app.exec();
}

通过设置循环,使得图像展示2.5秒,usleep的时间单位是microseconds,百万分之一秒。

emmmm,这样还是不够炫酷,加上个进度条吧!如何添加进度条呢?思路是在自定义的splashscreen里面划分为两部分:QWidget和QProgressBar,QWidget中放GIF,将processBar紧贴在其下面。

那这一步就不能再使用官方给的QSplashScreen了,自己写一个SplashScreen吧!继承QSplashScreen就OK了。
在Qt Creater里面的项目右键,add new…,C++ Class,主要新建mysplashscreen.h和mysplashscreen.cpp两个文件。
mysplashscreen.h
看代码:

#ifndef MYSPLASHSCREEN_H
#define MYSPLASHSCREEN_H
#include <QProgressBar>
#include <QSplashScreen>
class MySplashScreen : public QSplashScreen
{
    Q_OBJECT
public:MySplashScreen(QPixmap &pixmap, int time);~MySplashScreen();void setProgress();void generateAscendRandomNumber();QWidget *w;
private:QProgressBar *progressBar;QList<int> numberList;int elapseTime;
private slots:void updateProgress();
};
#endif // MYSPLASHSCREEN_H

mysplashscreen.cpp
在对象的构造函数中初始化成员变量,传入pixmap图像和总共显示的时间,新建进度条和QWidget对象。时然后生成100个递增的随机数存入列表中。
setProgress()将总时间分为100分,正好和100个数字相对应。使用定时器每隔相等的一段时间设置一下进度条的值,这个值可能是跳跃的,也可能相邻两项是相等的值,这就可以给人一种停顿感,而不是直接匀速达到100%。

#include "mysplashscreen.h"
#include <QDateTime>
#include <QProgressBar>
#include <QTimer>
#include <QDebug>
#include "unistd.h"
MySplashScreen::MySplashScreen(QPixmap &pixmap, int time):QSplashScreen (pixmap),elapseTime(time)
{
    w = new QWidget(this);w->setGeometry(0,0, 512, 256);progressBar = new QProgressBar(this);progressBar->setGeometry(0, w->height()-14, w->width(), 14);progressBar->setStyleSheet("QProgressBar{color:Gray;background-color:white;font:italic 10pt;text-align:center;}QProgressBar::chunk{background-color:rgb(0,0,0)}");progressBar->setRange(0,100);progressBar->setValue(0);generateAscendRandomNumber();setProgress();
}MySplashScreen::~MySplashScreen()
{
    
}void MySplashScreen::setProgress()
{
    int tempTime = elapseTime/100;for (int i=0; i<100; i++) {
    QTimer::singleShot(i*tempTime, this, SLOT(updateProgress()));}QTimer::singleShot(elapseTime, this, SLOT(close()));
}void MySplashScreen::generateAscendRandomNumber()
{
    int i;qsrand(static_cast<uint>(QTime(0,0,0).secsTo(QTime::currentTime())));for (i=0; i<100; i++) {
    numberList.append(qrand()%101);}std::sort(numberList.begin(), numberList.end());//qDebug() << "生成数字完毕: " << numberList;
}void MySplashScreen::updateProgress()
{
    static int num=0;progressBar->setValue(numberList[num]);//qDebug()<< numberList[num];num++;
}

main.cpp
需要注意的一点是这里splash传入的3000ms要和usleep()中的3000000微秒对应。

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);QPixmap pixmap(":/img/start_logo.gif");MySplashScreen splash(pixmap, 3000);QLabel label(splash.w);QMovie mv(":/img/start_logo.gif");label.setMovie(&mv);mv.start();splash.show();splash.setCursor(Qt::BlankCursor);for (int i=0; i<100; i++) {
    app.processEvents();usleep(30000);}MainWindow window;window.show();splash.finish(&window);return app.exec();
}

点击运行,就是开头的效果啦~

参考

https://blog.csdn.net/caoshangpa/article/details/51037427
https://blog.csdn.net/wangyachao0803/article/details/82839101

  相关解决方案