Qt总结之八:绘制仪表盘
前言
(1)QPainter用来执行具体的绘图相关的操作,用来画点,线,填充,变换,alpha/阿尔法通道(透明度)
*Appha的值越大,就越不透明,范围是0-255,255就是不透明,0就是完全透明;当对应 RGB 颜色时,
Alpha 会叠加到颜色上面;只有当 Alpha 通道是255时,才是其真正的颜色。*
(2)QPainterDevice是Qpainter用来绘图设备,Qt中有几种绘图的设备,如QWidget,Qpainter,QPaxmip
都是从QPainterDevice继承的。例如QPainter painter(this); 把绘图设备指针传递painter,把当前控件指针初始化。
(3)QPainterEngine类提供了不同类型设备接口,对程序员不透明,由QPainter,QpaintDevive类进行交互
一个绘图的操作流程就是:对一个QPainterDevice直接或间接调用Qpainter类。Qpainter类内部调用QpaintEngine进行绘图,而(4)QPainterEngine类通常是由QPainterDevice类负责创建和管理。
Qwidget类,最低层的类,接收鼠标,键盘和从其他敞口系统的事件,并且绘制在屏幕上。
(5)QPaintDevice类是所有可以绘制的对象的基类。个绘制设备就是一个可以使用QPainter来绘制的二维空间的抽象。绘画的能力由子类QWidget、QPixmap、QPicture和QPrinter来实现。绘制设备的默认坐标系统的原点在左上角。X向右增加,Y向下增加。单位是一个像素。这里有几种方法在使用绘制工具时来设置用户自定义的坐标系统,
(6)Qt 绘图系统定义了两个绘制时使用的关键属性:画刷和画笔。(1)画刷使用QBrush描述,大多用于填充;(2)画笔使用QPen描述,大多用于绘制轮廓线。
(7)QBrush定义了QPainter的填充模式,具有样式、颜色、渐变以及纹理等属性。画刷的style()定义了填充的样式,使用Qt::BrushStyle枚举,默认值是Qt::NoBrush,也就是不进行任何填充。QPen定义了用于QPainter应该怎样画线或者轮廓线。画笔具有样式、宽度、画刷、笔帽样式和连接样式等属性。画笔的样式style()定义了线的样式。画刷brush()用于填充画笔所绘制的线条。
参考网址:http://blog.csdn.net/zhang_xch/article/details/9051067
一、绘制
绘图的基本函数`
#ifndef SPEED_H
#define SPEED_H#include <QtWidgets/QWidget>
#include "ui_speed.h"class Speed : public QWidget
{Q_OBJECTpublic:Speed(QWidget *parent = 0);~Speed();protected:void paintEvent(QPaintEvent *);void drawCrown(QPainter *painter);void drawBackground(QPainter *painter);void drawScale(QPainter *painter);void drawScaleNum(QPainter *painter);void drawTitle(QPainter *painter);void drawIndicator(QPainter *painter);void drawNumericValue(QPainter *painter);private:QColor m_background;QColor m_foreground;int m_maxValue;int m_minValue;int m_startAngle;int m_endAngle;int m_scaleMajor;int m_scaleMinor;double m_value;int m_precision;QTimer *m_updateTimer;QString m_units;QString m_title;public Q_SLOTS:void UpdateAngle();private:Ui::SpeedClass ui;
};#endif // SPEED_H
上面的代码是能够绘画出图片的重要函数-重绘函数。只要出现以下几种情况,系统就会自动调用paintEvent方法。
a)当窗口部件第一次显示时,系统会自动产生一个绘图事件
b)重新调整窗口部件大小
c)当窗口部件被其他部件遮挡,然后又再次显示出来时,就会对隐藏的区域产生一个重绘事件
translate(qreal dx, qreal dy);坐标变换可以看做是painter当前的一个状态,我们可以用save()方法把当前的状态存到一个堆栈里,在用过 之后,再用restore()恢复
注:
坐标系统在绘制的过程中是至关重要的,首先做好坐标变换,把窗体的中心设置成坐标原点,(默认的坐标原点的窗体的左上方(0,0)向右是x->增长,向下是y->增长。)
二、绘制仪表盘
1.绘制表冠
首先就要绘制出两个个圆形,设置圆形的背景色,背景色采用渐变填充的方式,通过两个设置两个圆不同的填充颜色来形成一个色环,形成表冠。函数如下。使用的是线性渐变 QLinearGradient
QLinearGradient(qreal xStart, qreal yStart, qreal xFinalStop, qreal yFinalStop);
使用这个类实例化一个对象。对象的四个参数,分别是 两个点的坐标,表示渐变的方向。
setColorAt(qreal pos, const QColor &color);
pos是一个[0,1]的闭区间的数字。设置渐变坐标所表示的距离。的比例大小,0.2就是长度的1/5
painter->save();
painter->restore();
基本上都是一起出现的,前者是保存当前坐标,然后进行变换操,后者是将以前的坐标系状 态恢复,其实就是一个入栈和出栈的操作。
void Speed::drawCrown(QPainter *painter) //绘制表冠
{
painter->save();
int radius = 100;
QLinearGradient lg1(0, -radius, 0, radius);lg1.setColorAt(0, Qt::white); //设置渐变的颜色和路径比例
lg1.setColorAt(1, Qt::gray); //只是粗略的颜色,具体的可以参考RGB颜色查询对照表painter->setBrush(lg1); // 创建QBrush对象,把这个渐变对象传递进去:
painter->setPen(Qt::NoPen); //边框线无色
painter->drawEllipse(-rad ius, -radius, radius << 1, radius << 1);
painter->setBrush(m_background = Qt::black);
painter->drawEllipse(-92, -92, 184, 184);
painter->restore();
}
2.绘制刻度值
通过一套算法来实现绘制数字刻度
void Speed::drawScaleNum(QPainter *painter) //绘制刻度数字
{
painter->save();
painter->setPen(m_foreground);
//m_startAngle是起始角度,m_endAngle是结束角度,m_scaleMajor在一个量程中分成的刻度数
double startRad = ( 270-m_startAngle) * (3.14 / 180);
double deltaRad = (360 - m_startAngle - m_endAngle) * (3.14 / 180) / m_scaleMajor;
double sina,cosa;
int x, y;
QFontMetricsF fm(this->font());
double w, h, tmpVal;
QString str;for (int i = 0; i <= m_scaleMajor; i++)
{sina = sin(startRad - i * deltaRad);cosa = cos(startRad - i * deltaRad);tmpVal = 1.0 * i *((m_maxValue - m_minValue) / m_scaleMajor) + m_minValue;// tmpVal = 50;str = QString( "%1" ).arg(tmpVal); //%1作为占位符 arg()函数比起 sprintf()来是类型安全的w = fm.size(Qt::TextSingleLine,str).width();h = fm.size(Qt::TextSingleLine,str).height();x = 82 * cosa - w / 2;y = -82 * sina + h / 4;painter->drawText(x, y, str); //函数的前两个参数是显示的坐标位置,后一个是显示的内容,是字符类型""}
painter->restore();
3.绘制刻度线
rotate(qreal a);//函数实现角度的旋转
void Speed::drawScale(QPainter *painter) //绘制刻度线
{
painter->save();
painter->rotate(m_startAngle);
int steps = (m_scaleMajor * m_scaleMinor); //相乘后的值是分的份数
double angleStep = (360.0 - m_startAngle - m_endAngle) / steps; //每一个份数的角度// painter->setPen(m_foreground); //m_foreground是颜色的设置
// QPen pen = painter->pen(); //第一种方法
QPen pen ;
pen.setColor(Qt::green); //推荐使用第二种方式
for (int i = 0; i <= steps; i++)
{
if (i % m_scaleMinor == 0)//整数刻度显示加粗
{
pen.setWidth(1); //设置线宽
painter->setPen(pen); //使用面向对象的思想,把画笔关联上画家。通过画家画出来painter->drawLine(0, 62, 0, 72); //两个参数应该是两个坐标值}else{pen.setWidth(0);painter->setPen(pen);painter->drawLine(0, 67, 0, 72);}painter->rotate(angleStep);
}
painter->restore();
4.绘制标题
void Speed::drawTitle(QPainter *painter)
{
painter->save();
painter->setPen(m_foreground);
//painter->setBrush(m_foreground);
QString str(m_title); //显示仪表的功能
QFontMetricsF fm(this->font());
double w = fm.size(Qt::TextSingleLine,str).width();
painter->drawText(-w / 2, -30, str);
painter->restore();
}
5.显示的单位,与数值
void Speed::drawNumericValue(QPainter *painter)
{
QString str = QString(“%1 %2”).arg(m_value, 0, ‘f’, m_precision).arg(m_units);
QFontMetricsF fm(font());
double w = fm.size(Qt::TextSingleLine,str).width();
painter->setPen(m_foreground);
painter->drawText(-w / 2, 42, str);
}
6.绘制表针,和中心点
void Speed::drawIndicator(QPainter *painter)
{painter->save();QPolygon pts;pts.setPoints(3, -2, 0, 2, 0, 0, 60); /* (-2,0)/(2,0)/(0,60) *///第一个参数是 ,坐标的个数。后边的是坐标painter->rotate(m_startAngle);double degRotate = (360.0 - m_startAngle - m_endAngle) / (m_maxValue - m_minValue)*(m_value - m_minValue);//画指针painter->rotate(degRotate); //顺时针旋转坐标系统QRadialGradient haloGradient(0, 0, 60, 0, 0); //辐射渐变haloGradient.setColorAt(0, QColor(60, 60, 60));haloGradient.setColorAt(1, QColor(160, 160, 160)); //灰painter->setPen(Qt::white); //定义线条文本颜色 设置线条的颜色painter->setBrush(haloGradient);//刷子定义形状如何填满 填充后的颜色painter->drawConvexPolygon(pts); //这是个重载函数,绘制多边形。painter->restore();//画中心点QColor niceBlue(150, 150, 200);QConicalGradient coneGradient(0, 0, -90.0); //角度渐变coneGradient.setColorAt(0.0, Qt::darkGray);coneGradient.setColorAt(0.2, niceBlue);coneGradient.setColorAt(0.5, Qt::white);coneGradient.setColorAt(1.0, Qt::darkGray);painter->setPen(Qt::NoPen); //没有线,填满没有边界painter->setBrush(coneGradient);painter->drawEllipse(-5, -5, 10, 10);
}
7.重绘函数
void Speed ::paintEvent(QPaintEvent *)
{ QPainter painter(this);//一个类中的this表示一个指向该类自己的指针painter.setRenderHint(QPainter::Antialiasing); /* 使用反锯齿(如果可用) */painter.translate(width() / 2, height() / 2); /* 坐标变换为窗体中心 */int side = qMin(width(), height());painter.scale(side / 200.0, side / 200.0); /* 比例缩放 */drawCrown(&painter); /* 画表盘边框 */drawScaleNum(&painter); /* 画刻度数值值 */drawScale(&painter); /* 画刻度线 */drawTitle(&painter); /* 画单位 */drawNumericValue(&painter); /* 画数字显示 */drawIndicator(&painter); /* 画表针 */}
8.构造函数的初始化
m_background = Qt::black;m_foreground = Qt::green;m_startAngle = 60;m_endAngle = 60;m_scaleMajor = 10;m_minValue = 0;m_maxValue = 100;m_scaleMajor = 10;//分度m_scaleMinor = 10;m_units = "km/h";m_title = "Speed Meter";m_precision = 0;m_value = 0;m_updateTimer = new QTimer(this);m_updateTimer->setInterval(50);//间隔,微妙微单位,大家可以改一下这个值看看转动速度。connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(UpdateAngle()));m_updateTimer->start();//启动定时器setWindowFlags(Qt::FramelessWindowHint);//无窗体setAttribute(Qt::WA_TranslucentBackground);//背景透明resize(400, 400);
效果图
表盘中海添加了定时器,来实现动态的效果
Qt总结之八:绘制仪表盘相关推荐
- QT用QWT绘制心电图、脉氧饱和度波形图、波形图
qwt是一个基于LGPL版权协议的开源项目, 可生成各种统计图.它为具有技术专业背景的程序提供GUI组件和一组实用类,其目标是以基于2D方式的窗体部件来显示数据, 数据源以数值,数组或一组浮点数等方式 ...
- 【QT 5 相关实验-仪表盘-学习笔记-表盘组件练习与使用总结】
[QT 5 相关实验-仪表盘-学习笔记-表盘组件练习与使用总结] 1.概述 2.实验环境 3.参考资料-致谢 4.自我提升+实验效果 5.代码练习-学习后拆解 (1)头文件部分 (2)绘制事件+绘制表 ...
- python 仪表盘-跟小白学Python数据分析——绘制仪表盘
本文继续采用 PyEchartsv1.x版本进行绘制仪表盘. 注: PyEcharts分为 v0.5.x 和 v1.x 两个大版本,v0.5.x 和 v1.x 间不兼容,v0.5.x是基于Python ...
- python 仪表盘数据显示_跟小白学Python数据分析——绘制仪表盘
本文继续采用 PyEchartsv1.x版本进行绘制仪表盘. 注: PyEcharts分为 v0.5.x 和 v1.x 两个大版本,v0.5.x 和 v1.x 间不兼容,v0.5.x是基于Python ...
- 【Visual C++】游戏开发笔记四十 浅墨DirectX教程之八 绘制真实质感的三维世界:光照与材质专场...
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 作者:毛星云(浅墨) 邮箱: happylifemxy@163.com 本篇文章里,我们对Direct3D之中固定功能流水线中的3D ...
- 【Visual C++】游戏开发笔记四十 浅墨DirectX教程之八 绘制真实质感的三维世界 光照与材质专场
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...
- Qt使用OpenGL绘制图形
OpenGL与Qt Qt使用OpenGL绘制图形介绍 例程: 绘制点 绘制多边形 使用缓存 为图形设置颜色 实现3D效果 Qt使用OpenGL绘制图形介绍 QOpenGLWidget类是一个用来渲染O ...
- Qt QPainter鼠标绘制线条、矩形、多边形
Qt通过鼠标绘制线条.矩形.多边形本质都是根据鼠标的坐标位移,使用QPainter的自带的函数进行绘制.具体代码如下: graphicspainter.h #ifndef GRAPHICSPAINTE ...
- QT 圆形头像绘制方法
QT 圆形头像绘制方法 目标效果: 方法一: 将目标图像转换成圆形.根据图像得到圆形的Pixmap,再将pixmap绘制到label上. 这种方法的优点是不必在意绘制的label的形状是什么.相当于目 ...
最新文章
- vuejs学习笔记(1)--属性,事件绑定,ajax
- MySQL集群(一)之主从复制
- stm32怎么查看什么原因引起的nmi_为什么会有口臭,口臭是什么原因引起的,口臭是怎么回事...
- C#二维和多维数组编程实例
- 【模板】可持久化线段树 1(主席树)
- Angular jasmine单元测试框架里使用it函数定义single spec
- 2019 ICPC Asia Yinchuan Regional(9 / 13)
- 科目三-变更车道,直线行驶和超车的考试标准
- Knative Serving 之路由管理和 Ingress
- Odin插件与基于元数据的编辑器实现
- 百度AI之百度图像识别java版本使用
- 单片机是什么?51单片机和stm32有什么区别?
- 计算机应用基础网课作业答案,知到网课答案计算机应用基础(新)全部答案
- 自训练和半监督学习介绍
- iOS 的 APP 如何适应 iPhone 5s/6/6Plus 三种屏幕的尺寸?
- 解决:Establishing SSL connection without server‘s identity verification is not recommended警告
- 互联网下半场的基本玩法
- 我的第一堂职业素质课
- Pegasus 在 Apache Conf 上的分享
- 40个web前端实战项目,练完即可就业,从入门到进阶,基础到框架,html_css【附视频+源码】
热门文章
- 魅族“携手”京东,背后有何意图?
- cursor游标(mysql)
- 愁绪千万端,扰乱不成眠——如何修复Noise?
- wireshark----教你如何抓包
- SystemVerilog中package(包)的基本使用
- MySQL中实现rownum功能类似的语句
- 咬肌边上有个滑动疙瘩_猫逆子一个:摔杯子咬箱子,时常给我甩脸子!
- 防碰撞算法c语言,RFID防碰撞 二进制树形搜索算法 C语言实现
- 灵眸action_DJI OSMO Action 灵眸运动相机
- android中gridview实现动态表格,Android--GridView实现动态文字排版