QT5.12 简单自定义时钟、油表盘的制作代码(全)

在网上找到制作表盘的代码都不全,有的代码还需要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++;
        }


}


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值