在仪表盘专题中我们介绍如何通过继承重写QWidget的绘制事件paintEvent(),来绘制仪表盘。
本章节介绍如何绘制仪表盘的轮廓。
下一章节《图形绘制-仪表盘(2)-CSDN博客》介绍如何绘制刻度对应的数字及指针。
创建代码文件及头文件
dashboard.h头文件代码如下:
#ifndef DASHBOARD_H
#define DASHBOARD_H
#include
#include
class Dashboard : public QWidget
{
Q_OBJECT
public:
explicit Dashboard(QWidget *parent = nullptr);
//重写绘制函数
void paintEvent(QPaintEvent *event) override;
signals:
private:
int m_startAngle;
int m_endAngle;
int m_refSize; //绘制的参考大小
int m_radius;
int m_minSpeed;//最小刻度值
int m_maxSpeed;//最大刻度值
int m_curSpeed;//当前刻度值
int m_nultiple;//刻度间隔、比例 与上边的最大绘制刻度是整除关系
};
#endif // DASHBOARD_H
dashboard.cpp代码文件如下:
#include "dashboard.h"
Dashboard::Dashboard(QWidget *parent) : QWidget(parent)
{
m_startAngle = 150; //顺时针角度
m_endAngle = 30;
m_refSize = 200;
m_radius = m_refSize/2;
m_minSpeed = 0; //最小绘制刻度
m_maxSpeed = 100; //最大绘制刻度
m_nultiple = 1; //刻度间隔、比例 与上边的最大绘制刻度是整除关系
m_curSpeed = m_minSpeed;
}
//重写绘制函数
void Dashboard::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);// 抗锯齿
/*绘制圆*/
float scale = qMin(width(),height());
painter.scale(scale/m_refSize,scale/m_refSize);//缩放比例
painter.translate(m_refSize/2,m_refSize/2); //设置坐标原点
painter.setPen(Qt::NoPen);//无边框
painter.setBrush(QColor(58, 209, 255));//设置画笔颜色
painter.drawEllipse(-m_radius,-m_radius,m_refSize,m_refSize);//画圆
/*灰色背景色覆盖下半圆,效果比较立体*/
QPen pen;
pen.setCapStyle(Qt::FlatCap);
pen.setWidthF(10);
pen.setColor(QColor(88, 88, 88));
painter.setPen(pen);
QRectF rect = QRectF(-90, -90, 90 * 2, 90 * 2);
painter.drawArc(rect, -30 * 16, -120 * 16);
/*中间灰色圆圈覆盖*/
painter.setBrush(QColor(88, 88, 88));
painter.drawEllipse(QPoint(0,0),81,81);
/*绘制刻度*/
painter.rotate(m_startAngle);//将坐标系顺时针旋转150°,到达起始位置
QPen penScale(Qt::blue);
painter.setPen(penScale);
int step = (m_maxSpeed - m_minSpeed) / (5*m_nultiple);
double angleStep = (360.0 - (m_startAngle - m_endAngle)) / step;
for (int i = m_minSpeed; i
{
if (i >= (100*m_nultiple)){ //绘制红色
penScale.setColor(Qt::red);
painter.setPen(penScale);
}
if (i % (25*m_nultiple) == 0){//粗线
penScale.setWidth(2);
painter.setPen(penScale);
painter.drawLine(94,0,82,0);
}else if (i % (10*m_nultiple) == 0){//中等
penScale.setWidth(1);
painter.setPen(penScale);
painter.drawLine(94,0,84,0);
}else if (i % (5*m_nultiple) == 0){ //短线
penScale.setWidth(0);
painter.setPen(penScale);
painter.drawLine(90,0,86,0);
}
painter.rotate(angleStep); //将坐标系顺时针旋转48°
}
// 恢复到之前保存的状态,确保不影响其他绘图操作
// painter.restore();
}
几个关键步骤效果如下:
使用时,在MainWindow.ui窗体上,加一个verticalLayout(布局控件)
在MainWindow.cpp代码文件的构造函数中写以下代码:
引用dashboard.h头文件
#include "dashboard.h"
创建仪表盘控件的实例
Dashboard * dashboard = new Dashboard(this);
ui->verticalLayout->addWidget(dashboard);
运行效果如下