在网上找到制作表盘的代码都不全,有的代码还需要C币,哎,今天就简单的制作一个简单的例程
说明:直接复制.h文件和.cpp文件就可以制作完成
附上效果图:
表盘的数字可以查找
double textWidth = fontMetrics().width(“1”);
注意:图片上的红" . ”是表盘数字的位置,可通过删除painter.drawPoint(x,y); 去掉
MainWindow.h的头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPainter>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void drawFrame(QPainter &painter);
void drawNumberIndicator(QPainter &painter);
void drawDividing(QPainter &painter);
void drawNumberSpeed(QPainter &painter);
void drawIndicator(QPainter &painter);
protected:
void paintEvent(QPaintEvent *);
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
double m_refSize;
QWidget *m_wgt_mileage;
qreal m_radius;
int m_minSpeed;
int m_maxSpeed;
int m_startAngle;
int m_anglePerVel;
int m_endAngle;
int m_curSpeed;
};
#endif // MAINWINDOW_H
MainWindow.cpp的代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QtMath>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_wgt_mileage =new QWidget(this);
m_minSpeed=0;
m_maxSpeed=100;
m_startAngle=150;
m_refSize=200;
m_radius=100; // 大黑⚪
m_curSpeed=0;
m_endAngle=30;
m_anglePerVel =5;
}
/*
问题:setPen的作用???
*/
MainWindow::~MainWindow()
{
delete ui;
}
///
/// 函数会在任何页面需要重绘的时候被自动调用,来绘制窗口。
/// 所有带有自定义内容的窗口都必须重新实现该函数
/// 使用QPainter进行自定义绘制只能在paintEvent()函数或paintEvent()调用的函数中进行。
/// 可以手动调用update()或者repaint()函数来立刻通知系统调用paintEvent()函数,
/// 但是通常update()能获得更好的显示效果,因为它允许Qt进行速度优化和最小的闪烁。
///
void MainWindow::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.translate(m_refSize,m_refSize);
drawFrame(painter); //绘制边框
drawDividing(painter);//绘制刻度
drawNumberIndicator(painter);//绘制指示数字
drawNumberSpeed(painter);//显示数字速度
drawIndicator(painter);//绘制速度指针
// QPoint pos = m_wgt_mileage->mapFromParent(QPoint(-m_wgt_mileage->width()/2,40));
m_wgt_mileage->setGeometry((width() - m_wgt_mileage->width()) / 2 + 30,height() - m_wgt_mileage->height() - 60,m_wgt_mileage->width(),m_wgt_mileage->height());
}
//绘制边框
void MainWindow::drawFrame(QPainter &painter)
{
painter.save(); //保存原点位置
painter.setPen(Qt::NoPen);//确保没有边框线----填满,不留边界线
QLinearGradient lg1(-m_radius,-m_radius,m_radius,m_radius);//线性渐变 渐变区域
lg1.setColorAt(0,Qt::white); //0是停止点,用于渐变
lg1.setColorAt(1,Qt::black);
lg1.setSpread(QGradient::ReflectSpread);//渐变样式(颜色传播样式)
painter.setBrush(lg1); //画笔填充物
painter.drawEllipse(-m_radius,-m_radius,m_refSize,m_refSize);//画笔绘画,绘制一个椭圆------>画完会回到原点
//-------------画个小圆----------------//
painter.setBrush(Qt::black);
painter.drawEllipse(QPoint(0,0),90,90);
painter.restore();
}
//绘制刻度(主要用了 Qpainter::rotate)
void MainWindow::drawDividing(QPainter &painter)
{
painter.save();
// QPen pen(Qt::green);
// painter.setPen(pen);
// painter.drawLine(88,0,80,0);
painter.rotate(m_startAngle);//将坐标系顺时针旋转150°,到达起始位置
QPen pen(Qt::white);
painter.setPen(pen);
painter.drawLine(88,0,80,0);
int step = (m_maxSpeed - m_minSpeed) / 5; //每一个线条之间距离5
double angleStep = (360.0 - (m_startAngle - m_endAngle)) / step; //坐标系每走一步旋转的角度 360 - (开始角度 - 结束角度)/每次转的间隔
m_anglePerVel = angleStep;
for (int i = m_minSpeed; i <= m_maxSpeed; i += 5)
{
if (i >= 140){ //绘制红色
pen.setColor(Qt::red);
painter.setPen(pen);
}
if (i % 20 == 0){//粗线
pen.setWidth(2);
painter.setPen(pen);
painter.drawLine(88,0,75,0);
}else if (i % 10 == 0){//中等
pen.setWidth(1);
painter.setPen(pen);
painter.drawLine(88,0,80,0);
}else if (i % 5 == 0){ //短线
pen.setWidth(0);
painter.setPen(pen);
painter.drawLine(83,0,80,0);
}
// QPen pen1(Qt::yellow);
// painter.setPen(pen1);
// painter.drawRect(0,0,100,100);
painter.rotate(angleStep); //在之前的基础上原点坐标旋转angleStep度
}
painter.restore();
}
/**
圆点坐标:(x0,y0)
半径:r
角度:a0
则圆上任一点为:(x1,y1)
x1 = x0 + r * cos(ao * 3.14 /180 )
y1 = y0 + r * sin(ao * 3.14 /180 )
*/
//绘制数字指示
void MainWindow::drawNumberIndicator(QPainter &painter)
{
painter.save();//(100,100)
painter.setPen(Qt::red);
double x,y;
double angle, angleArc;
double w,h;
QFontMetricsF fm(this->font());//获取字体
painter.setPen(Qt::red);
painter.drawText(100,100,"ewwqewqeqw");
int anglestart = 150;
int step = (m_maxSpeed - m_minSpeed)/5;
double angleStep = (360.0 - (m_startAngle - m_endAngle)) / step;
for (int i = 0; i <= 5; i++)//每隔20Km设置一个数字
{
double textWidth = fontMetrics().width("1");
double textHeight = fontMetrics().height();
qDebug()<<textWidth<<","<<textHeight;
x = 0 + 70 * cos((anglestart * M_PI) /180 ) -textWidth/2;
y = 0 + 70 * sin((anglestart * M_PI) /180 )+textHeight/2;
painter.drawText(x,y,"1");
painter.drawPoint(x,y);
anglestart+=(angleStep*4);
}
painter.restore();
}
//显示KM/H
///
/// painter::drawText
///
void MainWindow::drawNumberSpeed(QPainter &painter)
{
painter.save();
painter.setPen(Qt::white);
QString speed = QString("%1 KM/H").arg(m_curSpeed*5);
QFontMetricsF fm(this->font());
qreal w = fm.size(Qt::TextSingleLine,speed).width(); //TextSingleLine 忽略换行符,返回给定文本中字符的大小(以像素为单位)
painter.drawText(-w/2,-20,speed); //本来想文字在0,-20,但是这样的话文字站了从头到尾巴占了(0~w,20)
painter.drawPoint(0,0);
painter.drawPoint(-w/2,-20);
painter.restore();
}
void MainWindow::drawIndicator(QPainter &painter)
{
painter.save();
//绘制指针
double curAngle = m_startAngle + m_curSpeed * m_anglePerVel;
painter.rotate(curAngle); //旋转坐标系
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);//刷子定义形状如何填满 填充后的颜色
static const QPointF points[3] = {
QPointF(0.0, 4),
QPointF(0.0, -4),
QPointF(68.0, 0),
};
painter.drawPolygon(points,3); //绘制多边形
painter.restore();
painter.save();
//绘制旋转中心
QRadialGradient rg(0,0,10);
rg.setColorAt(0.0,Qt::darkGray);
rg.setColorAt(0.5,Qt::white);
rg.setColorAt(1.0,Qt::darkGray);
painter.setPen(Qt::NoPen);
painter.setBrush(rg);
painter.drawEllipse(QPoint(0,0),10,10);
painter.restore();
}
void MainWindow::on_pushButton_clicked()
{
update();
if((m_curSpeed*5) == m_maxSpeed)
m_curSpeed=0;
else {
m_curSpeed++;
}
}