用QT+painter画仪表盘

用QT+painter画仪表盘

有些图形或者精美设计的可以用painter画刷实现。

案例汽车仪表盘:实现代码:#include "mainwindow.h"

#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)

: QMainWindow(parent)

, ui(new Ui::MainWindow)

{

ui->setupUi(this);

setFixedSize(1280,800);

//设置背景墙

this->setStyleSheet("#MainWindow{background-image:url(:/res/pic/background.png)}");

//定时器动态增加时速

myTimer = new QTimer(this);

connect(myTimer,SIGNAL(timeout()),this,SLOT(slot_speed_changed()));

}

void MainWindow::paintEvent(QPaintEvent*)

{

QPainter painter(this);

int width=this->width();

int height=this->height() - 100;//移动仪表盘的高度

int radius=((width>height)?height:width)/2.0;//仪表盘的中心位置

//移动画笔到中下方

painter.translate(width/2,height*0.6);

//启用反锯齿

painter.setRenderHint(QPainter::Antialiasing, true);

painter.setPen(Qt::NoPen);

//设置画刷颜色

painter.setBrush(QColor(138,43,226));

DrawSmallScale(painter,radius-60);//刻度线

DrawDigital(painter,radius-90);//刻度数字

/*所有形状绘画*/

// DrawCircle_bom(painter,radius-40); //扇形大圆

DrawCircle(painter,radius-35); //渐变发光外扇形

DrawCircle_arc(painter,radius - 40);//动态扇形环

DrawPointer(painter,radius-130);//指针

DrawCircle_line(painter,radius-35); //最外细圆线

DrawCircle_bom_big(painter,radius-150);//中间大圆

DrawCircle_bom_shine(painter,radius - 230);//渐变发光内圈

DrawCircle_bom_small(painter,radius - 200);//中间小圆

DrawUnit(painter,radius - 390);//单位

DrawNum(painter,radius-300);//时速

}

//绘制外圈点

void MainWindow::DrawPoint(QPainter& painter,int radius)

{

//组装点的路径图

QPainterPath pointPath;

pointPath.moveTo(-2,-2);

pointPath.lineTo(2,-2);

pointPath.lineTo(2,2);

pointPath.lineTo(0,4);

pointPath.lineTo(-2,2);

//绘制13个小点

for(int i=0;i<13;++i){

QPointF point(0,0);

painter.save();

painter.setBrush(QColor(250,252,78));

//计算并移动绘图对象中心点

point.setX(radius*qCos(((210-i*20)*M_PI)/180));

point.setY(radius*qSin(((210-i*20)*M_PI)/180));

//计算并移动绘图对象的中心点

painter.translate(point.x(),-point.y());

//计算并选择绘图对象坐标

painter.rotate(-120+i*20);

//绘制路径

painter.drawPath(pointPath);

painter.restore();

}

}

void MainWindow::DrawDigital(QPainter& painter,int radius)

{

//设置画笔,画笔默认NOPEN

painter.setPen(QColor(255,255,255));

QFont font;

font.setFamily("Arial");

font.setPointSize(15);

font.setBold(true);

painter.setFont(font);

for(int i=0;i<13;++i){

QPointF point(0,0);

painter.save();

point.setX(radius*qCos(((210-i*20)*M_PI)/180));

point.setY(radius*qSin(((210-i*20)*M_PI)/180));

painter.translate(point.x(),-point.y());

painter.rotate(-120+i*20);

painter.drawText(-25, 0, 50, 20,Qt::AlignCenter,QString::number(i*20));

painter.restore();

}

//还原画笔

painter.setPen(Qt::NoPen);

}

void MainWindow::DrawCircle_bom(QPainter& painter,int radius)

{

//保存绘图对象

painter.save();

//计算大小圆路径

QPainterPath outRing;

outRing.moveTo(0,0);

outRing.arcTo(-radius,-radius, 2*radius,2*radius,-30,240);

outRing.closeSubpath();

//设置画刷

painter.setBrush(QColor(14,15,33));

painter.drawPath(outRing);

painter.restore();

}

void MainWindow::DrawCircle_bom_shine(QPainter& painter,int radius)

{

painter.save();

QRadialGradient radialGradient(0,0,radius,0,0);

// radialGradient.setColorAt(0.5,QColor(8,77,197));

radialGradient.setColorAt(0.5,QColor(10,68,185,150));

radialGradient.setColorAt(1.0,Qt::transparent);

painter.setBrush(QBrush(radialGradient));

painter.drawRect(-radius,-radius,2*(radius),2*(radius));

painter.restore();

}

void MainWindow::DrawCircle_bom_big(QPainter& painter,int radius)

{

//保存绘图对象

painter.save();

//计算大小圆路径

QPainterPath inRing;

inRing.moveTo(0,0);

inRing.addEllipse(-radius+50,-radius + 50,2*(radius-50),2*(radius-50));

//设置画刷

painter.setBrush(QColor(10,20,30));

painter.drawPath(inRing);

painter.restore();

}

void MainWindow::DrawCircle_bom_small(QPainter& painter,int radius)

{

//保存绘图对象

painter.save();

//计算大小圆路径

QPainterPath inRing;

inRing.moveTo(0,0);

inRing.addEllipse(-radius+50,-radius + 50,2*(radius-50),2*(radius-50));

//设置画刷

painter.setBrush(QColor(10,20,30));

painter.drawPath(inRing);

painter.restore();

}

void MainWindow::DrawCircle_arc(QPainter& painter,int radius)

{

QRect rect(-radius,-radius,2*radius,2*radius);

QConicalGradient Conical(0,0,-70);

Conical.setColorAt(0.1,QColor(255,88,127,200));//红色

Conical.setColorAt(0.5,QColor(53,179,251,150));//蓝色

painter.setBrush(Conical);

painter.drawPie(rect,210*16,-(degRotate)*16);

}

void MainWindow::DrawCircle(QPainter& painter,int radius)

{

//保存绘图对象

painter.save();

//计算大小圆路径

QPainterPath outRing;

QPainterPath inRing;

outRing.moveTo(0,0);

inRing.moveTo(0,0);

outRing.arcTo(-radius,-radius, 2*radius,2*radius,-30,240);

inRing.addEllipse(-radius+50,-radius + 50,2*(radius-50),2*(radius-50));

outRing.closeSubpath();

//设置渐变色k

QRadialGradient radialGradient(0,0,radius,0,0);

radialGradient.setColorAt(1,QColor(0,82,199));

radialGradient.setColorAt(0.92,Qt::transparent);

//设置画刷

painter.setBrush(radialGradient);

//大圆减小圆

painter.drawPath(outRing.subtracted(inRing));

painter.restore();

}

void MainWindow::DrawCircle_line(QPainter& painter,int radius)

{

//保存绘图对象

painter.save();

//计算大小圆路径

QPainterPath outRing;

QPainterPath inRing;

outRing.moveTo(0,0);

inRing.moveTo(0,0);

outRing.arcTo(-radius,-radius, 2*radius,2*radius,-30,240);

inRing.addEllipse(-radius+2,-radius+2,2*(radius-2),2*(radius-2));

outRing.closeSubpath();

//设置画刷

painter.setBrush(QColor(5,228,255));

//大圆减小圆

painter.drawPath(outRing.subtracted(inRing));

painter.restore();

}

//绘制刻度

void MainWindow::DrawSmallScale(QPainter& painter,int radius)

{

//组装点的路径图

QPainterPath pointPath_small;

pointPath_small.moveTo(-2,-2);

pointPath_small.lineTo(2,-2);

pointPath_small.lineTo(2,8);

pointPath_small.lineTo(-2,8);

QPainterPath pointPath_big;

pointPath_big.moveTo(-2,-2);

pointPath_big.lineTo(2,-2);

pointPath_big.lineTo(2,20);

pointPath_big.lineTo(-2,20);

//绘制121个小点

for(int i=0;i<121;i+=2){

QPointF point(0,0);

painter.save();

point.setX(radius*qCos(((210-i*2)*M_PI)/180));

point.setY(radius*qSin(((210-i*2)*M_PI)/180));

painter.translate(point.x(),-point.y());

painter.rotate(-120+i*2);

if(i<80)

{

painter.setBrush(QColor(255,255,255));

}

if(i>=80)

{

painter.setBrush(QColor(235,70,70));

}

if(i%5 == 0)

{

painter.drawPath(pointPath_big);//绘画大刻度

}else

{

painter.drawPath(pointPath_small);//绘画小刻度

}

painter.restore();

}

}

//绘制文字

void MainWindow::DrawUnit(QPainter& painter,int radius)

{

painter.save();

painter.setPen(QColor(255,255,255));

QFont font;

font.setFamily("Arial");

font.setPointSize(16);

font.setBold(true);

painter.setFont(font);

painter.drawText(-50, -radius, 100, 20,Qt::AlignCenter,QString("km/h"));

painter.drawText(-60, -radius + 130, 120, 40,Qt::AlignCenter,QString(u8"当前车速"));

painter.setPen(QColor(255,255,255,50));

painter.drawText(-120, -radius + 280, 250, 40,Qt::AlignCenter,QString(u8"-请按space键加速-"));

painter.restore();

}

//绘制实时时速数字

void MainWindow::DrawNum(QPainter& painter,int radius)

{

painter.save();

painter.setPen(QColor(255,255,255));

QFont font;

font.setFamily("Arial");

font.setPointSize(45);

painter.setFont(font);

painter.drawText(-75, -radius - 20, 150, 100,Qt::AlignCenter,QString::number(degRotate));

painter.restore();

}

//绘制指针

void MainWindow::DrawPointer(QPainter& painter,int radius)

{

//组装点的路径图

QPainterPath pointPath;

pointPath.moveTo(10,0);

pointPath.lineTo(1,-radius);

pointPath.lineTo(-1,-radius);

pointPath.lineTo(-10,0);

pointPath.arcTo(-10,0,20,20,180,180);

QPainterPath inRing;

inRing.addEllipse(-5,-5,10,10);

painter.save();

//计算并选择绘图对象坐标

painter.rotate(degRotate - 120);

painter.setBrush(QColor(255,255,255));

painter.drawPath(pointPath.subtracted(inRing));

painter.restore();

}

//动态增加时速画面效果

void MainWindow::slot_speed_changed()

{

if(direction == 1)//加速

{

degRotate++;

if(degRotate > 240)

degRotate = 240;

}

else if(direction == 0)//减速

{

degRotate--;

if(degRotate < 0)

{

degRotate = 0;

myTimer->stop();

}

}

update();//刷新画面。很重要!

}

void MainWindow::keyPressEvent(QKeyEvent *event)

{

if(event->key() == Qt::Key_Space)

{

if(direction == 0)

{

myTimer->start(1);

direction = 1;

}

}

}

//按键释放事件

void MainWindow::keyReleaseEvent(QKeyEvent *event)

{

if(event->key() == Qt::Key_Space)

{

direction = 0;

}

}

MainWindow::~MainWindow()

{

delete ui;

}代码分析:QPainter QPainter的核心功能是绘图,但该类也提供了几个函数,允许用户自定义QPainter的设置及其渲染质量,以及其他支持剪切的功能。此外,还可以通过指定画家的构图模式来控制不同的形状如何合并在一起。QPainter只能在paintEvent()函数中或被paintEvent()调用的函数中使用。

上面代码常用的一些设置:

//移动画笔到中下方

painter.translate(width/2,height*0.6);

//启用反锯齿

painter.setRenderHint(QPainter::Antialiasing, true);

painter.setPen(Qt::NoPen);

//设置画刷颜色

painter.setBrush(QColor(138,43,226));常用的函数:

drawEllipsevoid QPainter::drawEllipse(const QRectF &rectangle)上面主要是画椭圆,但前提是要给定长方形,在其中画椭圆

addEllipsevoid QPainterPath::addEllipse(qreal x, qreal y, qreal w, qreal h)上面函数是椭圆或圆或圆弧,当x,y两个点为正方形,画的为圆

//-radius+50,-radius + 50 是以此为坐标点,创建一个高为2*(radius-50),宽为2*(radius-50)的内切圆

inRing.addEllipse(-radius+50,-radius + 50,2*(radius-50),2*(radius-50));

//arcTo

void QPainterPath::arcTo(qreal x, qreal y, qreal w, qreal h, qreal startAngle, qreal arcLength)跟addEllipse一样也是创建内切圆,但是它定义了起始位置

//定义 内切圆后去-30到240度的圆弧,逆时针绘制所以是-30度到240度

outRing.arcTo(-radius,-radius, 2*radius,2*radius,-30,240);

内切圆的用法:

//保存绘图对象

painter.save();

//计算大小圆路径

QPainterPath outRing;

QPainterPath inRing;

outRing.moveTo(0,0);

inRing.moveTo(0,0);

outRing.arcTo(-radius,-radius, 2*radius,2*radius,-30,240);

inRing.addEllipse(-radius+50,-radius+50,2*(radius-50),2*(radius-50));

outRing.closeSubpath();

//设置渐变色k

QRadialGradient radialGradient(0,0,radius,0,0);

radialGradient.setColorAt(1,QColor(0,82,199));

radialGradient.setColorAt(0.92,Qt::transparent);

//设置画刷

painter.setBrush(radialGradient);

//大圆减小圆

painter.drawPath(outRing.subtracted(inRing));

painter.restore();translate变更坐标原点

inline void QPainter::translate(qreal dx, qreal dy)//将坐标原点变更为 point.x(),-point.y()

QPointF point(0,0);

painter.save();

//应用三角函数知识确定x,y坐标的位置

point.setX(radius*qCos(((210-i*2)*M_PI)/180));

point.setY(radius*qSin(((210-i*2)*M_PI)/180));

painter.translate(point.x(),-point.y());rotate

顺时针旋转一个角度

//因为画是个圆弧,两边各多了30度,可以将此行注释点观察,不旋转的样子,来进行推断

painter.rotate(-120+i*2);

相关故事

那有养兔子养殖基地 哪里有种兔养殖基地
mobile365体育手机版入口

那有养兔子养殖基地 哪里有种兔养殖基地

王者荣耀S21老夫子出装铭文攻略 什么?又大了七八个
mobile365体育手机版入口

王者荣耀S21老夫子出装铭文攻略 什么?又大了七八个

走进天翼云
任丘36524便利店电话

走进天翼云