Qt自定义控件画图实现漂亮的仪表盘,附完整demo源码

在现代应用程序中,仪表盘是一种直观的方式,用于展示各种数据。使用 Qt 创建自定义控件,可以帮助我们绘制出功能强大且美观的仪表盘。本篇博文将带你深入理解如何通过具体的代码示例,实现一个类似于汽车速度表的仪表盘。

基于QT的仪表盘有很多种办法,比如使用QWT,ChartDirector 或H5混合的echart组件,或者基于QT的绘图功能绘制,或者基于美工提供的图片的基础上增加动态效果。然而搞明白QT自定义控件的绘图后,自定义绘图这种,实现是最简单最轻量级的。且定制度高,想要什么效果就可以自己绘制个。

所谓一通百通,有了以下示例的参考实现,任意实现一个类似的仪表盘,也是很简单的事情了。以下四个完整示例,是我们将要讨论的关键点。 

工程demo源码下载https://download.youkuaiyun.com/download/qq8864/90047925

 

初始化

在 MySpeed 类的构造函数中,我们设置了一些基本的属性,包括:

  • 背景颜色和前景颜色:定义了仪表盘的背景和前景颜色。
  • 速度值:用于模拟的当前速度,范围从 0 到 100。
  • 单位和标题:定义了仪表盘显示的单位(湿度/%RH)和标题。
  • 角度和刻度:定义了起始和结束角度以及刻度线的数量。
m_background = QColor(50, 154, 255, 200);
m_foreground = Qt::white;

speed = 0;
status = 0;
m_startAngle = 45;
m_endAngle = 45;
m_minValue = 0;
m_maxValue = 100;
m_scaleMajor = 10;  // 分度
m_scaleMinor = 10;  
m_units = "湿度/%RH";
m_title = "";
m_precision = 2;
m_value = 0;

m_angle = (qreal)270/(m_maxValue-1);
time_id = this->startTimer(50);

绘制事件

我们重写了 paintEvent 方法,在其中使用 QPainter 绘制仪表盘。

void MySpeed::paintEvent(QPaintEvent *event)
{
    int width = this->width();
    int height = this->height();
    QPainter painter(this);

    painter.translate(width / 2, height / 2); // 将原点移动到控件中心
    int side = qMin(width, height);
    painter.scale(side / 200.0, side / 200.0); // 等比缩放

    drawFrame(&painter);     // 绘制仪表盘框架
    drawScale(&painter);     // 绘制刻度线
    drawScaleNum(&painter);  // 绘制刻度数字
    drawUnit(&painter);      // 绘制单位
    drawPointer(&painter);   // 绘制指针
    drawSpeed(&painter);     // 绘制当前速度
}

绘制仪表盘框架

drawFrame 方法绘制了仪表盘的背景和形状。我们使用 QLinearGradient 创建一个渐变效果。

void MySpeed::drawFrame(QPainter *painter)
{
    painter->save();
    int radius = 100;
    QLinearGradient lg1(0, -radius, 0, radius);
    lg1.setColorAt(0, Qt::white);
    lg1.setColorAt(1, Qt::gray);
    painter->setBrush(lg1);
    painter->setPen(Qt::NoPen);
    painter->drawEllipse(-radius, -radius, radius << 1, radius << 1);
    
    painter->setBrush(m_background);
    painter->drawEllipse(-92, -92, 184, 184);
    painter->restore();
}

绘制刻度和数字

在 drawScale 和 drawScaleNum 方法中,分别绘制了刻度线和刻度数字。使用三角函数确保刻度正确位置。

void MySpeed::drawScale(QPainter *painter)
{
    painter->save();
    painter->rotate(m_startAngle);
    int steps = (m_scaleMajor * m_scaleMinor);
    double angleStep = (360.0 - m_startAngle - m_endAngle) / steps;

    for (int i = 0; i <= steps; i++)
    {
        if (i % m_scaleMinor == 0)
            painter->drawLine(0, 90, 0, 98); // 主要刻度
        else
            painter->drawLine(0, 95, 0, 98); // 次要刻度
        painter->rotate(angleStep);
    }
    painter->restore();
}

绘制指针和速度

drawPointer 方法负责绘制指针,使用渐变来增加视觉效果。drawSpeed 方法则绘制当前的速度值。

void MySpeed::drawPointer(QPainter *painter)
{
    int radius = 100;
    QPoint point[4] = {
        QPoint(0, 10),
        QPoint(-10, 0),
        QPoint(0, -80),
        QPoint(10, 0),
    };

    painter->save();
    // 绘制指针的逻辑...
    painter->restore();
}

void MySpeed::drawSpeed(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::white);
    QFont font("Times", 10, QFont::Bold);
    font.setBold(true);
    font.setPixelSize(42);
    painter->setFont(font);
    painter->drawText(-60, 0, 120, 92, Qt::AlignCenter, QString::number(speed));
    painter->restore();
}

连接定时器和动态效果

通过 timerEvent 方法,我们可以动态改变速度值以模拟速度表的运动。定时器每 50 毫秒触发一次,更新当前速度并重绘仪表盘。

void MySpeed::timerEvent(QTimerEvent *e)
{
    // 动态变化速度
}

总结

通过以上的代码示例,我们成功实现了一个基本的仪表盘控件。掌握了这一实现方法后,您可以根据需要扩展仪表的功能,并为其他类型的仪表创建类似的绘制逻辑。Qt 的强大绘图能力和自定义控件机制,使我们能够轻松实现丰富多彩的用户界面。希望这些示例能为您设计其他仪表盘提供灵感和帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

特立独行的猫a

您的鼓励是我的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值