Qt仪表自绘

小王子🤴 2020-09-20 21:34:22 4641
Qt仪表自绘

本片文章介绍仪表控件是如何绘制的,首先上图:

绘制原理:
根据上图介绍绘制的原理,继承QWidget类,重写绘制事件函数:
protected:
void paintEvent(QPaintEvent *);
在绘制事件中绘制仪表。
仪表绘制分为五个部分:绘制外弧线、绘制刻度颜色块,绘制圆心、绘制指针、绘制显示文本。
绘制外弧线:
首先先绘制一个外饼形圆、然后再绘制一个内饼形圆,内外圆颜色不同,这样就会形成一个外弧线:

绘制刻度色块:
使用弧线绘制一块一块的弧度色块,色块间隔空白的地方也是弧线色块只是背景色是透明色:

绘制圆心:
在最下方水平中心的地方绘制一个圆:

绘制指针:
以圆心为起点,要指向的位置为终点绘制一条指针直线

绘制显示文本:
在圆心的下方绘制指针指向的值

以上就是仪表绘制的步骤。
仪表控件类封装:

#ifndef DASHBOARD_H
#define DASHBOARD_H

#include <QWidget>
#include <QPainter>
#include <QDebug>
#include <qmath.h>

class Dashboard : public QWidget
{
    Q_OBJECT
public:
    explicit Dashboard(QWidget *parent = nullptr);
    void setValue(double value);
    void setTextFromat(QString value);
    void setTextFont(QFont font);
    double getValue();
    QString getTextFromat();
    QFont getTextFont();
signals:

public slots:

protected:
    void paintEvent(QPaintEvent *);
    void drawCircular(QPainter *painter);//绘制圆弧
    void drawScale(QPainter *painter);//绘制刻度
    void drawCenterCircle(QPainter *painter);//绘制中心圆
    void drawPointerIndicator(QPainter *painter);//绘制指针
    void drawValue(QPainter *painter);//绘制Text

private:
    double minValue;                //最小值
    double maxValue;                //最大值
    double value;                   //目标值
    int precision;                  //精确度,小数点后几位
    int startAngle;                 //开始旋转角度
    int endAngle;                   //结束旋转角度
    QColor outerCircleColor;        //外圆背景颜色
    QColor innerCircleColor;        //内圆背景颜色
    QColor pieColor1;           //饼圆颜色1
    QColor pieColor2;             //饼圆颜色2
    QColor pieColor3;             //饼圆颜色3
    QColor pieColor4;           //饼圆颜色4
    QColor pieColor5;             //饼圆颜色5
    QColor pieColor6;             //饼圆颜色6
    QColor pieColor7;             //饼圆颜色7
    QColor coverCircleColor;        //覆盖圆背景颜色
    QColor scaleColor;              //刻度尺颜色
    QColor pointerColor;            //指针颜色
    QColor centerCircleColor;       //中心圆颜色
    QColor textColor;               //文字颜色
    double currentValue;            //当前值
    QString textFromat;//文本格式
    QFont textFont;//文本字体

};

#endif // DASHBOARD_H

#include "dashboard.h"

Dashboard::Dashboard(QWidget *parent) : QWidget(parent)
{
    outerCircleColor = QColor(80,80,80);        //外圆背景颜色
    innerCircleColor = QColor(60,60,60);        //内圆背景颜色

    pieColor1 = QColor(0,128,64);           //饼圆颜色1
    pieColor2 = QColor(0,64,0);             //饼圆颜色2
    pieColor3 = QColor(0,0,255);             //饼圆颜色3
    pieColor4 = QColor(255,128,0);           //饼圆颜色4
    pieColor5 = QColor(128,0,255);             //饼圆颜色5
    pieColor6 = QColor(128,0,0);             //饼圆颜色6
    pieColor7 = QColor(255,0,0);             //饼圆颜色7

    coverCircleColor = QColor(255,0,0);        //覆盖圆背景颜色
    scaleColor = QColor(252,252,252);              //刻度尺颜色
    pointerColor = QColor(65,234,0);            //指针颜色
    centerCircleColor = QColor(65,234,0);       //中心圆颜色
    textColor = QColor(0, 0, 0);       //文本颜色

    minValue = 0;                //最小值
    maxValue = 100;                //最大值
    value = 0;                   //目标值

    startAngle = 90;                 //开始旋转角度
    endAngle = 270;                   //结束旋转角度

    currentValue = 77.6;            //当前值

    textFromat = "%1";

    textFont.setPixelSize(18);

}

void Dashboard::setValue(double value)
{
    currentValue = value;            //当前值
}

void Dashboard::setTextFromat(QString value)
{
    textFromat = value;
}

void Dashboard::setTextFont(QFont font)
{
    textFont = font;
}

double Dashboard::getValue()
{
    return currentValue;
}

QString Dashboard::getTextFromat()
{
    return textFromat;
}

QFont Dashboard::getTextFont()
{
    return textFont;
}

void Dashboard::paintEvent(QPaintEvent *)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    //绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
    QPainter painter(this);
    painter.save();
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    painter.translate(width / 2, height - height / 3);//平移坐标轴 将中心点作为原点(0,0)
    painter.scale(side / 200.0, side / 200.0);//缩放坐标轴系统

    drawCircular(&painter);//外弧线
    drawScale(&painter);//刻度标
    drawCenterCircle(&painter);//绘制中心圆
    drawPointerIndicator(&painter);//绘制指针
    drawValue(&painter);//绘制文本

    painter.restore();
}

void Dashboard::drawCircular(QPainter *painter)
{
    int radius = 100/*100*/;
    QRectF rect(-radius, -radius, radius * 2, radius * 2);
    painter->save();
    painter->setPen(Qt::NoPen);
    //绘制开始饼圆
    painter->setBrush(outerCircleColor);
    painter->drawPie(rect,-3 * 16, 186 * 16);

    radius = 95/*95*/;
    rect = QRectF(-radius, -radius, radius * 2, radius * 2);
    painter->setPen(QPen(QBrush(QColor(255,255,255)),1,Qt::SolidLine)/*Qt::NoPen*/);
    painter->setBrush(QColor(255,255,0/*255*/));
    painter->drawPie(rect,-3 * 16, 186 * 16);

    painter->restore();
}

void Dashboard::drawScale(QPainter *painter)
{
    int radius = 85;
    QRectF rect(-radius, -radius, radius * 2, radius * 2);
    painter->save();
    painter->setPen(Qt::NoPen);

    int start = -1;
    for(int i = 0;i < 21;i ++)
    {
        if(i/3 < 1)
        {
            painter->setPen(QPen(pieColor7,6,Qt::SolidLine));
            painter->setBrush(pieColor7);
        }else if (i/3 < 2) {
            painter->setPen(QPen(pieColor6,6,Qt::SolidLine));
            painter->setBrush(pieColor6);

        }else if (i/3 < 3){
            painter->setPen(QPen(pieColor5,6,Qt::SolidLine));
            painter->setBrush(pieColor5);
        }else if (i/3 < 4){
            painter->setPen(QPen(pieColor4,6,Qt::SolidLine));
            painter->setBrush(pieColor4);
        }else if (i/3 < 5){
            painter->setPen(QPen(pieColor3,6,Qt::SolidLine));
            painter->setBrush(pieColor3);
        }else if (i/3 < 6){
            painter->setPen(QPen(pieColor2,6,Qt::SolidLine));
            painter->setBrush(pieColor2);
        }else {
            painter->setPen(QPen(pieColor1,6,Qt::SolidLine));
            painter->setBrush(pieColor1);
        }

        painter->drawArc(rect,start*16, 2*16);
        start = start + 6;

        painter->setPen(QPen(QColor(255, 255, 255,0),6,Qt::SolidLine));
        painter->setBrush(QColor(255, 255, 255,0));
        painter->drawArc(rect,start*16, 3*16);
        start = start + 3;
    }

    painter->restore();
}

void Dashboard::drawCenterCircle(QPainter *painter)
{
    int radius = 8;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(centerCircleColor);
    painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
    painter->restore();
}

void Dashboard::drawPointerIndicator(QPainter *painter)
{
    int radius = 75;
    painter->save();
    painter->setOpacity(1.0);
    painter->setPen(QPen(pointerColor,4));
    painter->setBrush(pointerColor);

    QPolygon pts;
    pts.setPoints(4, -5, 0, 5, 0, -5, radius,5,radius);

    painter->rotate(startAngle);
    double degRotate = (360.0 - qAbs(startAngle - endAngle)) / (maxValue - minValue) * (currentValue - minValue);
    painter->rotate(degRotate);
    painter->drawLine(0,0,0,75);

    painter->restore();
}

void Dashboard::drawValue(QPainter *painter)
{    painter->save();
    painter->setPen(textColor);
    painter->setFont(textFont);

    qDebug() << this->width();
    QRect textRect(-200, 10, 400, 400);
    QString strValue = textFromat.arg(static_cast<double>(currentValue));
    painter->drawText(textRect, Qt::AlignTop | Qt::AlignHCenter, strValue);

    painter->restore();
}
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 1 2 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
小王子🤴
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区