Qt实现汽车仪表盘

qt · 浏览次数 : 23

小编点评

这段内容主要描述了一个UI界面设计的过程,包括多个函数及其实现细节,用以创建一个仪表盘应用。具体来说,这些函数用于绘制画布、小圆、刻度线、刻度值、指针、扇形、渐变内圆、黑色内圈、当前数值和Logo图标等组件。 1. **绘制画布**:该函数用于初始化绘图环境,设置抗锯齿功能和背景色。 - `painter.setRenderHint(QPainter::Antialiasing, true)`:启用抗锯齿功能,使绘制效果更平滑。 - `painter.setBrush(QColor(0, 0, 0))`:设置画笔颜色为黑色。 - `painter.drawRect(rect())`:绘制一个矩形作为画布。 2. **画中心小圆**:该函数用于绘制仪表盘中心的小圆。 - `painter.setPen(QPen(QColor(255, 255, 255), 3))`:设置画笔颜色和宽度。 - `painter.drawEllipse(QPoint(0, 0), radius, radius)`:绘制一个以原点为中心、半径为指定值的圆。 3. **画仪表盘刻度线**:该函数用于绘制仪表盘的刻度线。 - `angle = 240 * 1.0 / 60`:计算每个刻度的角度。 - 使用循环遍历并绘制不同风格的刻度线。 4. **画刻度值**:该函数用于绘制刻度上的数值。 - `painter.setFont(QFont("Arial", 15))`:设置字体类型和大小。 - 使用循环遍历并绘制每个刻度的数值。 5. **画指针**:该函数用于绘制仪表盘指针。 - 使用向量图形(多边形)来模拟指针的转动。 6. **画扇形**:该函数用于绘制指针扫过的扇形区域。 - 定义扇形绘制区域,并使用扇形绘制方法绘制。 7. **画渐变的内圆**:该函数用于绘制内圆,带有渐变色。 - 使用QRadialGradient创建渐变背景。 8. **画黑色内圈**:该函数用于绘制作为速度值和单位背景的黑色内圈。 - 设置画刷颜色为黑色,并绘制圆形。 9. **绘制当前数值**:该函数用于绘制仪表盘上的当前速度数值。 - 设置字体类型和大小,绘制数值和单位。 10. **绘制发光外壳**:该函数用于绘制仪表盘的外壳和发光外圈。 - 使用扇形绘制方法和渐变色设置,绘制外壳。 总的来说,这个UI界面设计过程涉及了大量的绘图操作和坐标变换,通过一系列函数实现了仪表盘应用的各个组件的绘制。

正文

在UI界面显示中,仪表盘的应用相对比较广泛,经常用于显示速度值,电压电流值等等,最终实现效果如下动态图片(文末提供给源工程下载):

 

主要包含以下绘制步骤:

  1. 绘制画布
    /*
     * 绘制画布
    */
    void Widget::initCanvas(QPainter &painter)
    {
        //消除锯齿
        painter.setRenderHint(QPainter::Antialiasing,true);
        //设置底色
        painter.setBrush(QColor(0,0,0));
        painter.drawRect(rect());
        //平移坐标系原点位置
        QPoint center(rect().width()/2, rect().height()*0.6);
        painter.translate(center);
    }

    实现效果:

  2. 画中心小圆
    /*
     * 画小圆
    */
    void Widget::drawMiddleCircle(QPainter &painter, int radius)
    {
        //设置画笔颜色和宽度
        painter.setPen(QPen(QColor(255,255,255),3));
        //原点坐标(0,0)绘制半径为radius的圆
        painter.drawEllipse(QPoint(0,0), radius, radius);
    }

    实现效果:

  3. 画仪表盘刻度线
    /*
     * 画刻度
    */
    void Widget::drawScaleLine(QPainter &painter, int radius)
    {
        //总计60个小刻度,每一个小刻度的角度值
        angle = 240*1.0 / 60;
        //保存当前坐标
        painter.save();
        painter.setPen(QPen(Qt::white, 5));
        //设置起始刻度位置
        painter.rotate(startAngle);
        for(int i=0; i <=60; i++)
        {
            if( i>=40 )
            {
                //第40个刻度后,绘制画笔修改成红色
                painter.setPen(QPen(Qt::red, 5));
            }
            if(i%5 == 0)
            {
                //绘制长刻度
                painter.drawLine(radius-20, 0, radius-3, 0);
            }
            else
            {
                //绘制短刻度
                painter.drawLine(radius-8, 0, radius-3, 0);
            }
            //绘制完一个刻度旋转一次坐标
            painter.rotate(angle);
        }
        //恢复坐标
        painter.restore();
        painter.setPen(QPen(Qt::white, 5));
    }

    实现效果:

  4. 绘制刻度值
    /*
     * 画刻度值
    */
    void Widget::drawScaleValue(QPainter &painter, int radius)
    {
        //设置字体类型和大小
        QFont textFont("Arial",15);
        //设置粗体
        textFont.setBold(true);
        painter.setFont(textFont);
        int text_r = radius - 49;
        for(int i=0; i<=60; i++)
        {
            if(i%5 == 0)
            {
                if(i>=40)
                {
                    painter.setPen(QPen(Qt::red, 5));
                }
                //保存当前坐标系
                painter.save();
                int delX = qCos((210-angle*i)*M_PI/180) * text_r;
                int delY = qSin(qDegreesToRadians(210-angle*i)) * text_r;
                //平移坐标系
                painter.translate(QPoint(delX,-delY));
                //旋转坐标系
                painter.rotate(-120+angle*i);
                //写上刻度值,文字居中
                painter.drawText(-25,-25,50,30,Qt::AlignCenter,QString::number(i*4));
                //恢复坐标系
                painter.restore();
            }
        }
        painter.setPen(QPen(Qt::white, 5));
    }

    实现效果:

  5. 绘制仪表指针
    /*
     * 画指针
    */
    void Widget::drawPoint(QPainter &painter, int radius)
    {
        //保存当前坐标
        painter.save();
        //设置画刷颜色
        painter.setBrush(Qt::white);
        //设置画笔为无线条
        painter.setPen(Qt::NoPen);
        static const QPointF points[4] = {
            QPointF(0, 0.0),
            QPointF(radius*2.0/3, -1.1),
            QPointF(radius*2.0/3, 1.1),
            QPointF(0, 15.0)
        };
        //坐标选旋转
        painter.rotate(startAngle + angle * currentValue);
        //绘制多边形
        painter.drawPolygon(points, 4);
        //恢复坐标
        painter.restore();
    }

    实现效果:

  6. 绘制指针扫过的扇形
    /*
     * 画扇形
    */
    void Widget::drawSpeedSector(QPainter &painter, int radius)
    {
        //定义矩形区域
        QRect rentangle(-radius, -radius, radius*2, radius*2);
        //设置画笔无线条
        painter.setPen(Qt::NoPen);
        //设置画刷颜色
        painter.setBrush(QColor(255,0,0,80));
        //绘制扇形
        painter.drawPie(rentangle, (360-startAngle)*16, -angle*currentValue*16);
    }

    实现效果:

  7. 绘制渐变的内圆
    /*
     * 画渐变内圆
    */
    void Widget::drawInnerEllipse(QPainter &painter, int radius)
    {
        QRadialGradient radial(0,0,radius);
        //中心颜色
        radial.setColorAt(0.0,QColor(255,0,0,200));
        //外围颜色
        radial.setColorAt(1.0,QColor(0,0,0,100));
        //设置画刷渐变色
        painter.setBrush(radial);
        //画圆形
        painter.drawEllipse(QPoint(0,0), radius, radius);
    }

    实现效果:

  8. 绘制黑色内圈(用于显示速度值和单位的背景圆)
    /*
     * 画黑色内圈
    */
    void Widget::drawInnerEllipseBlack(QPainter &painter, int radius)
    {
        //设置画刷
        painter.setBrush(Qt::black);
        //绘制圆形
        painter.drawEllipse(QPoint(0,0), radius, radius);
    }

    实现效果:

  9. 绘制当前数值
    /*
     * 绘制当前数值
    */
    void Widget::drawCurrentSpeed(QPainter &painter)
    {
        painter.setPen(Qt::white);
        //绘制数值
        QFont font("Arial", 28);
        font.setBold(true);
        painter.setFont(font);
        painter.drawText(QRect(-60,-60,120,70),Qt::AlignCenter,QString::number(currentValue*4));
        //绘制单位
        QFont font_u("Arial", 13);
        painter.setFont(font_u);
        painter.drawText(QRect(-60,-60,120,160),Qt::AlignCenter,"km/h");
    }

    实现效果:

  10. 绘制发光外壳
    /*
     * 画外壳,发光外圈
    */
    void Widget::drawEllipseOutSkirts(QPainter &painter, int radius)
    {
        //设置扇形绘制区域
        QRect outAngle(-radius, -radius, 2*radius, 2*radius);
        painter.setPen(Qt::NoPen);
        //设置渐变色
        QRadialGradient radia(0,0,radius);
        radia.setColorAt(1,QColor(255,0,0,200));
        radia.setColorAt(0.97,QColor(255,0,0,120));
        radia.setColorAt(0.9,QColor(0,0,0,0));
        radia.setColorAt(0,QColor(0,0,0,0));
        painter.setBrush(radia);
        //绘制圆形
        painter.drawPie(outAngle,(360-150)*16,-angle*61*16);
    }

    实现效果:

  11. 绘制Logo图标
    /*
     * 画LOGO
    */
    void Widget::drawLogo(QPainter &painter, int radius)
    {
        //定义Logo绘制区域
        QRect rectLogo(-65,radius*0.38,130,50);
        painter.drawPixmap(rectLogo,QPixmap("./logo2.png"));
    }

    实现效果:

     

源码下载链接如下:

DashBoad https://www.alipan.com/s/injYzUTNr5n 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。

 

与Qt实现汽车仪表盘相似的内容:

Qt实现汽车仪表盘

在UI界面显示中,仪表盘的应用相对比较广泛,经常用于显示速度值,电压电流值等等,最终实现效果如下动态图片(文末提供给源工程下载): 主要包含以下绘制步骤: 绘制画布 /* * 绘制画布 */ void Widget::initCanvas(QPainter &painter) { //消除锯齿 pa

【Qt 6】读写剪贴板

剪贴板是个啥就不用多介绍了,最直观的功能是实现应用程序之间数据共享。就是咱们常说的“复制”、“粘贴”功能。 在 Qt 中,QClipboard 类提供了相关 API 让应用程序具备读/写剪贴板的能力。数据通过 QMimeData 类包装。该类使用 MIME 类型来标识数据。比如,要包装的数据是纯文本

Qt Quick 用cmake怎么玩子项目

实际工程中,很多时候需要做到工程的分散,尤其是涉及到保密的源码模块。这里以Qt Quick为例基于cmake演示一遍工程的多项目化。

用 VS Code 搞 Qt6:让信号和槽自动建立连接

Qt 具备让某个对象的信号与符合要求的槽函数自动建立连接。弄起来也很简单,只要调用这个静态方法即可: QMetaObject::connectSlotsByName(...); connectSlotsByName 方法需要一个参数,此参数的指针指向一个实例,这个实例自身的信号,以及它的子级对象的信

QGIS开发笔记(二):Windows安装版二次开发环境搭建(上):安装OSGeo4W运行依赖其Qt的基础环境Demo

前言 使用QGis的目的是进行二次开发,或者说是融入我们的应用(无人车、无人船、无人机),本片描述搭建QGis二次基础开发环境,由于实在是太长了,进行了分篇: 上半部分:主要是安装好后,使用QtCreator可以使用QGIs的apps下的Qt使用对应的编译器编译不带qgis的空工程。 下半部分:在上

QGIS开发笔记(三):Windows安装版二次开发环境搭建(下):将QGis融入QtDemo,添加QGis并加载tif遥感图的Demo

前言 使用QGis的目的是进行二次开发,或者说是融入我们的应用(无人车、无人船、无人机),本片描述搭建QGis二次基础开发环境,由于实在是太长了,进行了分篇: 上半部分:主要是安装好后,使用QtCreator可以使用QGIs的apps下的Qt使用对应的编译器编译不带qgis的空工程。 下半部分:在上

逆向通达信 x 逆向微信 x 逆向Qt

本篇在博客园地址https://www.cnblogs.com/bbqzsl/p/18252961 本篇内容包括: win32窗口嵌入Qt UI。反斗玩转signal-slot。最后 通达信 x 微信 x Qt 做手术。 Qt Alien Widget是一种广义的DirectUI。 在UI技术中,D

Qt 应用程序中自定义鼠标光标

在 Qt 应用程序中,你可以自定义鼠标光标。你可以使用 `QCursor` 类来设置不同类型的鼠标光标,比如内置样式或者自定义的图片。以下是一些使用示例: 使用内置光标样式 Qt 提供了一些内置的光标样式,你可以使用这些样式来改变光标的外观,例如箭头、手形、等待图标等等。 1 #include

QT中各控件的属性和方法

1.在QT6中,QLabel类具有许多属性和方法,以下是QLabel类的常见属性和调用方法:setText(const QString &text):设置标签的文本内容。setAlignment(Qt::Alignment align):设置文本在标签中的对齐方式。setPixmap(const Q

[Qt开发]当我们在开发兼容高分辨率和高缩放比、高DPI屏幕的软件时,我们在谈论什么。

前言 最近在开发有关高分辨率屏幕的软件,还是做了不少尝试的,当然我们也去网上查了不少资料,但是网上的资料也很零碎,说不明白,这样的话我就做个简单的总结,希望看到这的你可以一次解决你有关不同分辨率下的所有问题。 分辨率?DPI? 首先我们搞清楚我们现在到底面对的是什么场景。在开发高分屏的时候,实际上不