您的位置:首页 > 编程语言 > Qt开发

[置顶] Qt自定义控件之进度条(代码实现)

2015-09-22 21:32 316 查看

Qt自定义控件之进度条(代码实现)

例子



宝马车的图标大家都很熟悉了。现在我们做一个这样的例子,旋转的宝马图标。我忘了这个例子是是在哪里下载的了,不过非常感谢那位作者。我在其这个例子的基础上扩展了一些控件。首先学这个例子,你得有Qt基础,会自己创建工程编译工程,其次要懂Qt最基本的2D绘图。

一、创建工程mybmw(我的别摸我^-^)

创建一个类控件继承与QWidget。我的开发环境是ubuntu + Qt4.8.1 + Qt Creator

mybmw.h

#ifndef MYBMW_H
#define MYBMW_H
//内部圆半径比例因子
#define RADIUS_FACTOR 0.8

//外部圆开始和停止颜色
#define OUTER_CIRCLE_START_COLOR QColor(65,65,65)
#define OUTER_CIRCLE_END_COLOR QColor(89,89,89)

//内部圆的蓝色
#define BLUE_CIRCLE_START_COLOR QColor(0,133,203)
#define BLUE_CIRCLE_END_COLOR QColor(0,118,177)
//内部圆的白色
#define WHITE_CIRCLE_START_COLOR QColor(255,255,255)
#define WHITE_CIRCLE_END_COLOR QColor(233,233,233)

#include <QWidget>
#include <QtGui>

class myBMW : public QWidget
{
Q_OBJECT
public:
explicit myBMW(QWidget *parent = 0);

protected:
void paintEvent(QPaintEvent *);

//重写sizeHint()
QSize sizeHint() const
{
return QSize(300,300);
}

private:
void drawUnderCircle(QPainter* painter);//画外圆

void drawBMW(QPainter* painter);//画宝马

private:
QTimer* m_updateTimer;//定时器时间

qreal   m_angle;    //旋转角度
qreal   m_outerRadius;//外半径

private slots:
void UpdateAngle();//自定义槽,更新角度旋转

};

#endif // MYBMW_H


mybmw.cpp

#include "mybmw.h"

myBMW::myBMW(QWidget *parent) :
QWidget(parent)
{
m_updateTimer = new QTimer(this);
m_updateTimer->setInterval(50);//间隔,微妙微单位,大家可以改一下这个值看看转动速度。
connect(m_updateTimer,SIGNAL(timeout()),this,SLOT(UpdateAngle()));
m_updateTimer->start();//启动定时器

m_angle = 0;
m_outerRadius = 0;
setWindowFlags(Qt::FramelessWindowHint);//无窗体
setAttribute(Qt::WA_TranslucentBackground);//背景透明
}

void myBMW::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing|QPainter::HighQualityAntialiasing);//设置反锯齿
drawUnderCircle(&painter);//画外部圆
drawBMW(&painter);//画宝马
}

void myBMW::drawUnderCircle(QPainter *painter)
{
painter->save();

m_outerRadius = width() > height() ? (qreal)height()/2-4 : (qreal)width()/2-4;//求最小的那个值。自己可以测试一下减4个像素与不减的区别

QPointF TopLeft(rect().center().x() - m_outerRadius,rect().center().y() - m_outerRadius);
QPointF BottomRight(rect().center().x() + m_outerRadius,rect().center().y() + m_outerRadius);
QRectF CircleRect(TopLeft,BottomRight);//大圆矩形

painter->setPen(Qt::NoPen);//大家可以注释掉这行看一下,有什么差别?
QRadialGradient CircleGradient(CircleRect.center(),m_outerRadius,CircleRect.center());//设置渐变
CircleGradient.setColorAt(0.0,OUTER_CIRCLE_START_COLOR);
CircleGradient.setColorAt(1.0,OUTER_CIRCLE_END_COLOR);
painter->setBrush(CircleGradient);

painter->drawEllipse(CircleRect);//画椭圆,其实就是画圆。特殊椭圆而已

painter->restore();
}

void myBMW::drawBMW(QPainter *painter)
{

painter->save();

//坐标转换的方法和下面直接用painter的rotate方法一样
//QTransform t;
//t.translate(rect().center().x(),rect().center().y());// move to center
//t.rotate(m_angle,Qt::ZAxis);//绕Z轴旋转
//painter->setTransform(t);

painter->translate(rect().center().x(),rect().center().y());// move to center
painter->rotate(m_angle);//旋转

qreal InnerRadius = m_outerRadius * RADIUS_FACTOR;//内半径
QPointF tTopLeft( -InnerRadius,-InnerRadius);
QPointF tBottomRight(InnerRadius,InnerRadius);
QRectF  tRect(tTopLeft,tBottomRight);

qreal dAngle = 90 * 16;//为什么乘以16?自己查看文档怎么画pie的。
qreal StartAngle = 0;

painter->setPen(Qt::NoPen);
for(int AngleIndex = 0; AngleIndex < 4;AngleIndex++)
{
//交叉蓝色白色
QRadialGradient PieGradient(tRect.center(),m_outerRadius,tRect.center());
if(AngleIndex%2)//蓝色
{
PieGradient.setColorAt(0.0,BLUE_CIRCLE_START_COLOR);
PieGradient.setColorAt(1.0,BLUE_CIRCLE_END_COLOR);
}
else//白色
{
PieGradient.setColorAt(0.0,WHITE_CIRCLE_START_COLOR);
PieGradient.setColorAt(1.0,WHITE_CIRCLE_END_COLOR);
}
painter->setBrush(PieGradient);
painter->drawPie(tRect,StartAngle,dAngle);

//角度增加90度
StartAngle += dAngle;
}

painter->restore();
}

void myBMW::UpdateAngle()
{
m_angle += 1;
if(m_angle > 360)
{
m_angle = 0;
}

//m_angle = ((m_angle + 1) % 360);与上面几行功能一样
update();//刷新控件,会调用paintEvent函数
}


写完之后编译一下,是不是看到旋转的宝马图标了呢?代码上面都有了,我注释的还算清晰吗,大家可以自己试一下。

二、举一反三

学习了上面的例子之后,我们可以小试牛刀,随便练练手,比如实现下面的6个。是不是很酷炫吊炸天

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: