软件启动进度条制作(使用自定义样式)

自定义进度条需要使用到两个类,一个是QSplashScreen,一个是QProgressBar。既然是自定义那么这两个类就需要继承重写。

QSplashScreen重写的MySplashScreen.h文件

#pragma once

#include <QObject>
#include <QSplashScreen>
#include <QPixmap>
#include <QWidget>
#include <QProgressBar>
#include <QTime>
#include <QCoreApplication>
#include "MyprogressBar.h"

class MySplashScreen : public QSplashScreen
{
	Q_OBJECT

public:
    MySplashScreen(QPixmap pixmap, QWidget* parent = 0);
	~MySplashScreen();
public:
    void setRange(int min, int max);//设置进度条大小
    void mySleep(int ms);//进度条每次更新间隔
    

public slots:
    void updateNum(int n);//进度条更新进度

protected:
    bool eventFilter(QObject* watched, QEvent* event); //使用事件过滤器,防止进度条在加载中的时候,用户点击了图片,造成窗口被隐藏
  
private:
    MyprogressBar* progressBar;//自己写的进度条类

};

 QSplashScreen重写的MySplashScreen.cpp文件

#include "MySplashScreen.h"

MySplashScreen::MySplashScreen(QPixmap pixmap, QWidget* parent) :
    QSplashScreen(parent, pixmap)
{
    installEventFilter(this);//设置事件发送
    progressBar = new MyprogressBar(this);
    progressBar->setAlignment(Qt::AlignCenter);
    progressBar->setGeometry(0, 0, pixmap.width(), pixmap.height());   // 设置进度条的位置

}


MySplashScreen::~MySplashScreen()
{
}

void MySplashScreen::setRange(int min, int max)
{
    progressBar->setRange(min, max);//进度条长度
}
void MySplashScreen::updateNum(int n)
{
    progressBar->setPro(n);//更新进度条进度
    mySleep(10);//停止10ms
    
}
void MySplashScreen::mySleep(int ms)
{
    QTime time = QTime::currentTime().addMSecs(ms);
    while (QTime::currentTime() < time) {
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }
}

bool MySplashScreen::eventFilter(QObject* watched, QEvent* event) // 使用事件过滤器,防止进度条在加载中的时候,用户点击了图片,造成窗口被隐藏 // 可以去除体验效果
{
    if (event->type() == QEvent::Type::MouseButtonPress || event->type() == QEvent::Type::MouseButtonDblClick)
    {
        return true;
    }
    return false;
}

QProgressBar 重写的MyProgressBar.h文件

#pragma once

#include <QObject>
#include <QBitmap>
#include <QDebug>
#include <QPainter>
#include <QLabel>
#include <QProgressBar>
#include <QPainterPath>




class MyprogressBar : public QProgressBar
{
	Q_OBJECT

public:
	MyprogressBar(QWidget *parent);
	~MyprogressBar();

    int mdir = 0;//设置进度条是横向加载还是纵向加载,0我写成横向加载
    int mPro;//加载进度值
    QPixmap mBack;//加载的背景图片
    QPixmap mProgress;//加载的进度条图片
  
public:
   
    void setPro(int mpro);//设置加载位置

    void paintEvent(QPaintEvent* paintEvent);
};

QProgressBar 重写的MyProgressBar.cpp文件

#include "MyprogressBar.h"
#pragma execution_character_set("utf-8")

MyprogressBar::MyprogressBar(QWidget*parent)
	: QProgressBar(parent)
{
    mProgress.load("./picture/bar.png");//获取加载的进度条图片
    this->setAutoFillBackground(true);//设置填满背景
    QPalette palette = this->palette();
    mBack.load("./picture/back.png");//设置加载进度条的背景图
    resize(mBack.size());
    setMask(mBack.mask());
    palette.setBrush(QPalette::Background, QBrush(mBack));
    setPalette(palette);
    mPro = 0;

}

MyprogressBar::~MyprogressBar()
{
}

void MyprogressBar::setPro(int pro)
{
    mPro = pro;
    update();
}


void MyprogressBar::paintEvent(QPaintEvent* paintEvent)
{
    Q_UNUSED(paintEvent);//避免编译器警告,作用不大
    int w = mProgress.width();
    int h = mProgress.height();
    QPixmap tempPixmap;
    int progressWidth;
    //copy进度条样式的一小段作为绘制使用
    
    if (mdir == 0)//进度条横向加载
    {
        progressWidth = mPro * w / 100;
        tempPixmap = mProgress.copy(0, 0, progressWidth, h);
    }
    else//进度条纵向加载
    {
        progressWidth = mPro * h / 100;
        tempPixmap = mProgress.copy(0, h, w, progressWidth);
    }

    QPainterPath progressPath;
    //QPainterPath,可以绘制自定义路径。这里将其处理为圆角矩形;
    //5个参数分别为x, y, w, h, roundness;
    //可以注意到这里的w是变量,即加载时的进度变化;
    //progressPath.addRoundRect(0, 0,progressWidth,24, 99);
    if (mdir == 0)
    {
        progressPath.addRect(0, 0, progressWidth, h);
    }
    else
    {
        progressPath.addRect(0, h - progressWidth, w, progressWidth);
    }
    QPainter painter(this);
    painter.setPen (QPen(Qt::NoPen));
    //设置Brush为上面的tempPixmap,即每次绘制出来都是进度条的样式;
    painter.setBrush(QBrush(tempPixmap));
    //设置抗锯齿
    painter.setRenderHints(QPainter::Antialiasing, true);
    //绘制前面定义好的QPainterPath
    painter.drawPath(progressPath);

    painter.setPen(QPen(Qt::green, 10, Qt::SolidLine, Qt::RoundCap));//在加载的图片中输入文字,想在进度条添加文字的可以家不想添加的不用加
    painter.drawText(QPoint(this->width()/2.5,this->height()/2),QString("软件已加载:%1%").arg(mPro));
}

进度条最主要的两个类写好了,下面我们就是使用他们(假进度条和真实的进度条制作)。

1.制作假进度条

如果只为添加进度条的使用效果告知软件在启动,我们可以直接做成假进度条(简单方便的就做到了提示效果)

假进度条我们只需要在main.cpp文件中使用就可以,直接上代码看效果。

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
	//启动动画点开软件先加载启动进度条
	QPixmap pix("./picture/bar.png");//获取背景进度图大小,设置进度条位置
	MySplashScreen  sp(pix);
	sp.setRange(0, 100);//进度条长度范围
	sp.show();
	a.processEvents();
	
    FreezerSystem w(&sp);//软件构造,即软件内容加载//有个sp是因为我使用真实进度条

	//软件加载完成进行进度条展示
	for (int i = 0; i < 100; i++)
	{
		sp.updateNum(i);
	}


	w.setWindowFlags(Qt::FramelessWindowHint);
    w.show();
    return a.exec();
}

效果图

这是软件加载完成后进度条才会动,进度条动起来说明软件是加载完成了,所以他会一直卡0%,你也可以一开始就设置99%。

下面是真进度条的使用,真进度条的使用。这进度条是根据软件里面初始化程度进行传输数值。

要使用真进度条我们就要将MySplashScreen放入软件的构造函数里面

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
	//启动动画点开软件先加载启动进度条
	QPixmap pix("./picture/bar.png");//获取背景进度图大小,设置进度条位置
	MySplashScreen  sp(pix);
	sp.setRange(0, 100);//进度条长度范围
	sp.show();
	a.processEvents();
	
    FreezerSystem w(&sp);//软件构造,即软件内容加载//有个sp是因为我使用真实进度条

	软件加载完成进行进度条展示
	//for (int i = 0; i < 100; i++)
	//{
	//	sp.updateNum(i);
	//}


	w.setWindowFlags(Qt::FramelessWindowHint);
    w.show();
    return a.exec();
}

其实真进度条就是将sp传入构造函数里面,通过在构造函数进行值传递。

将类传给构造函数,构造函数这样写。

FreezerSystem( MySplashScreen* sp ,QWidget *parent = Q_NULLPTR);//添加MySplashScreen

 然后就这样进行值传递,你每初始化完成一个就可以进行一次值传递来达到真实进度条。效果图就不展示了。

下面是我参考链接:有其他不同进度条要求的同学也可以看看他们的博客Qt笔记(四十六)之Qt设置启动动画(3)图片+进度条_我是黄同学的博客-CSDN博客_qsplashscreen进度条

 QT5制作定制进度条(二)_flash_Fox的博客-CSDN博客_qt 设置进度条样式

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值