本人qt菜鸡一枚,最近做项目时要用到进度条,然后查询资料发现qt有自己封装好的进度条QProgressBar和QProgressDialog,用了一下发现还可以就是有些不熟练,之前打算自己也封装一些控件练一下手,所以打算先试一下封装一个控件成进度条。简单的写了一下,仍有很多不足之处。
我是用的Qlabel封装的
#ifndef PROGRESSLABEL_H
#define PROGRESSLABEL_H
#include <QObject>
#include "generalheaders.h"
class Progresslabel : public QLabel
{
Q_OBJECT
public:
explicit Progresslabel(QWidget *parent = 0);
void setValue(int index);
void reset();
void setBgColor(QColor BgColor);
void setTextColor(QColor TextColor);
signals:
public slots:
protected:
void paintEvent(QPaintEvent *event);
private:
int StartX;
int StartY;
int labelW;
int labelH;
int Startx;
int Starty;
int labelw;
int labelh;
int textStartx;
int textStarty;
int textw;
int texth;
int ProgressNum;
QColor bgColor;
QColor textColor;
bool drawTextFlag;
};
#endif // PROGRESSLABEL_H
主体思路是这样的,在一个QLabel里面话一个空心矩形,然后在空心矩形里面画一个实心矩形,设置进度即为设置实心矩形宽度。
#include "progresslabel.h"
Progresslabel::Progresslabel(QWidget *parent) : QLabel(parent)
{
this->setMinimumWidth(250);
this->setMinimumHeight(25);
StartX = this->x();
StartY = this->y();
labelW = this->width();
labelH = this->height();
labelw = (((labelW*4)/5)*8)/10;
labelh = (labelH*8)/10;
Startx = StartX + labelW/10;
Starty = StartY + labelH/10;
textStartx = StartX + (labelW*4)/5;
textStarty = StartY;
textw = labelW/5;
texth = labelH;
ProgressNum = 0;
bgColor = QColor(0,0,0);
textColor = QColor(0,0,0);
drawTextFlag = false;
}
void Progresslabel::reset()
{
drawTextFlag = false;
}
void Progresslabel::setValue(int index)
{
drawTextFlag = true;
ProgressNum = index;
repaint();
}
void Progresslabel::setBgColor(QColor BgColor)
{
bgColor = BgColor;
}
void Progresslabel::setTextColor(QColor TextColor)
{
textColor = TextColor;
}
void Progresslabel::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QPen pen(bgColor, 1, Qt::SolidLine);
painter.setPen(pen);
QRectF rectF1 = QRectF(Startx,Starty,labelw,labelh);
painter.drawRect(rectF1);
painter.setBrush(bgColor);
QRectF rectF2 = QRectF(Startx,Starty,(ProgressNum*labelw)/100,labelh);
painter.drawRect(rectF2);
if(drawTextFlag)
{
QRectF rectF3 = QRectF(textStartx,textStarty,textw,texth);
QString text = QString::number(ProgressNum) + "%";
painter.setPen(textColor);
painter.drawText(rectF3,Qt::AlignCenter,text);
}
}
可以看到cpp部分paintEvent实心矩形的宽度设置为(ProgressNum*labelw)/100,labelw为最大宽度,ProgressNum为进度,然后函数setValue即为设置进度条状态,实际上设置实心矩形宽度实现的。
效果如下图:
此时没有进度然后在简单测试一下
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
lab1 = new Progresslabel(this);
lab1->setBgColor(QColor(255,0,0));
lab1->setTextColor(QColor(0,0,0));
lab1->reset();
btn1 = new QPushButton("Start",this);
QHBoxLayout *mainLayout = new QHBoxLayout(this);
mainLayout->addWidget(lab1);
mainLayout->addWidget(btn1);
this->setLayout(mainLayout);
connect(btn1,SIGNAL(clicked(bool)),this,SLOT(start()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::start()
{
for(int i=0;i<100;i++)
{
mysleep(100);
lab1->setValue(i+1);
}
}
void Widget::mysleep(int msc)
{
QTime _Timer = QTime::currentTime();
QTime _NowTimer;
do{
_NowTimer = QTime::currentTime();
}while (_Timer.msecsTo(_NowTimer)<= msc);
}
每100ms设置一下进度
大功告成!