#include "cardisp.h"
#include <QTimer>
#include <QDebug>
// 画圆时的半径
const int CarDisp::radius = 150;
// 最大值
const int CarDisp::maxv = 400;
// 最小值
const int CarDisp::minv = 0;
// 构造函数
CarDisp::CarDisp(QWidget *parent)
: QWidget(parent)
{
setWindowTitle("仪表盘");
// 运行时表针显示的值
Values = 0;
QTimer* t = new QTimer();//加入对象树
t->start(1000);
//以lambda表达式的形式设置槽函数
connect(t, &QTimer::timeout, [=]{
// qDebug() << "hello";
if(Values > (CarDisp::maxv-5))
{
Values = 0;
setvalues(Values);
}
else
{
Values += 10;
setvalues(Values);
}
});
}
// 析构函数
CarDisp::~CarDisp()
{
}
// 设置运行时表针显示的值
// 实现更新仪表盘指针
void CarDisp::setvalues(qreal iValues)
{
// 为仪表盘指针赋值
Values = iValues;
// 更新小部件,除非禁用更新或小部件被隐藏。
// 此函数不会导致立即重绘;相反,当Qt返回到主事件循环时,它调度一个绘画事件进行处理。
update();
}
// 绘制图像
// 系统内置函数是斜体显示
void CarDisp::paintEvent(QPaintEvent *event)
{
// 定义一个 QPainter 绘画类的变量
QPainter painter(this);
// 指示绘画引擎应该在可能的情况下消除原边缘的混叠
painter.setRenderHint(QPainter::Antialiasing);
// 计算出窗体的中心点
QPoint center(width()/2, height()/2);
// 保存当前的画工状态(将状态推入堆栈)
// 保存窗体中心点
painter.save();
// 绘制背景圆形
// 制定绘制图案的起点
painter.translate(center);
// 将画家的笔设置为给定的笔
// 笔定义了如何绘制线条和轮廓,它还定义了文本的颜色
// Qt::NoPen : 根本没有线。例如,QPainter::drawRect()填充但不绘制任何边界线。
painter.setPen(Qt::NoPen);
// 设置画笔颜色
painter.setBrush(QColor(142,142,142));
// 背景颜色应该大于仪表盘半径一点一点
const int bkRadius = radius + 3;
// 绘制半径为rx和ry的位于中心的椭圆。
painter.drawEllipse(QPoint(),bkRadius,bkRadius);
// 绘制刻度线
// 设置起始的偏移角度
painter.rotate(-135);
// 长线的总数量,从 0 开始,一共 11 个
const int longstep = 10;
// 短线的总数量,从 0 开始,一共 51 个
const int shortstep = 50;
// 使用 for 循环依次画出刻度线
for(int i = 0; i <= shortstep; i++)
{
// 前面80%刻度线为绿色,后面20%刻度线为红色
painter.setPen((i < shortstep * 0.8) ? QColor(32,243,32) : QColor(243,32,32));
if(i % (shortstep / longstep) != 0)
{
// 绘制短线
QPoint p1(0,-(radius-8)); // 线的起点
QPoint p2(0,-radius); // 线的终点
painter.drawLine(p1,p2);
}
else
{
// 绘制长线
QPoint p1(0,-(radius-14)); // 线的起点
QPoint p2(0,-radius); // 线的终点
painter.drawLine(p1,p2);
}
// 设置结束
painter.rotate(270.0/shortstep);
}
// 绘制仪表盘名称和背景矩形
painter.restore();
QFontMetrics fm=painter.fontMetrics();
int tx=center.x();
int ty=int(center.y()+(radius/1.4142));
QString title="仪表盘";
QSize tsz=fm.size(0,title);
QRect trect(QPoint(tx-tsz.width()/2,ty-tsz.height()/2),tsz);
painter.setPen(QColor(127,127,127));
painter.setBrush(QColor(173,163,163));
painter.drawRoundedRect(trect.adjusted(-6,-4,6,4),3,3);
painter.setPen(QColor(243,243,243));
painter.setBrush(Qt::NoBrush);
painter.drawText(trect,title); // 绘制每个长刻度对应的文字
painter.setPen(QColor(243,243,243));
const int hand=radius-21;
for(int i=0;i<=longstep;i++)
{
qreal angle=qDegreesToRadians(-135.0+i*(270.0/longstep));
QString etext=QString::number(minv+i*(maxv-minv)/longstep);
QPointF dirvec(qSin(angle),-qCos(angle));
QPointF ecenter(center.x()+hand*dirvec.x(),center.y()+hand*dirvec.y());
QSize esz=fm.size(0,etext);
QRectF erect(QPointF(ecenter.x()-esz.width()/2,ecenter.y()-esz.height()/2),esz);
painter.drawText(erect,etext);
}
// 仪表盘指针绘制
// 保存当前的画工状态(将状态推入堆栈)
painter.save();
QPoint triangle[]={
{-5,0},
{0,25-radius},
{5,0}
};
qreal degree=-135.0+270.0*(Values-minv)/(maxv-minv);
painter.translate(center);
painter.rotate(degree);
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::red);
painter.drawPolygon(triangle,3);
painter.setPen(QPen(QColor(214,0,0),2));
painter.drawEllipse(QPoint(),7,7);
painter.restore();
}
Qt 仪表盘
最新推荐文章于 2024-02-26 20:11:08 发布