自定义进度条需要使用到两个类,一个是QSplashScreen,一个是QProgressBar。既然是自定义那么这两个类就需要继承重写。
QSplashScreen重写的MySplashScreen.h文件
#pragma once
#include
#include
#include
#include
#include
#include
#include
#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
#include
#include
#include
#include
#include
#include
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 设置进度条样式
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)