0
点赞
收藏
分享

微信扫一扫

Qt 自绘温度计

编程练习生J 2022-01-20 阅读 25

使用Qt 自绘一个温度计,代码如下

1、头文件

#ifndef THERMOMETREDLG_H
#define THERMOMETREDLG_H

#include <QWidget>
#include <QPropertyAnimation>
#include <QPainter>
#include <QTimer>

class thermometreDlg : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(qreal value READ getValue WRITE setValue)  //声明属性

public:
    explicit thermometreDlg(QWidget *parent = nullptr);
    qreal getValue();
    void setValue(qreal value);
    void changeValue(qreal value);

protected:
    void paintEvent(QPaintEvent *e);

public slots:
    void startAnimation();

signals:

private:
    qreal m_value;
    qreal curValue;
    int m_width;
    QRectF m_rect;
    int maxValue, minValue;
    qreal m_radius;
    QPropertyAnimation *m_valueAnimation;
    void updateRect();


};

#endif // THERMOMETREDLG_H

2、源文件

#include "thermometredlg.h"
#include <QDebug>

thermometreDlg::thermometreDlg(QWidget *parent) : QWidget(parent)
{
    m_width = 20;
    maxValue = 30;
    minValue = -30;
    m_radius = 1.05;
    m_value = -25;
    curValue = m_value;
    QTimer *at = new QTimer(this);
    at->start(1000);
    m_valueAnimation = new QPropertyAnimation(this, "value");
    m_valueAnimation->setDuration(1000);
    m_valueAnimation->setEasingCurve(QEasingCurve::OutCubic);
    m_valueAnimation->setLoopCount(1);
    connect(at, SIGNAL(timeout()), this, SLOT(startAnimation()));

}


void thermometreDlg::updateRect()
{
    m_rect.setX(0);
    m_rect.setY(20 - height()/2);
    m_rect.setWidth(m_width);
    m_rect.setHeight(height() - 40 - m_width* m_radius);
}

void thermometreDlg::setValue(qreal value)
{
    m_value = value;
    update();
}

void thermometreDlg::changeValue(qreal value)
{
    if(value > maxValue)
        value = maxValue;
    if(value < minValue)
        value = minValue;
    curValue = value;
}

qreal thermometreDlg::getValue()
{
    return m_value;
}


void thermometreDlg::paintEvent(QPaintEvent *e)
{
    updateRect();
    QPainter painter(this);
    QPen pen(Qt::black);
    painter.translate(this->width()/2, this->height()/2);  //坐标轴移动到中心点
    painter.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing);  // 启用反锯齿
    painter.save();
    //绘制上方的柱状
    painter.fillRect(m_rect, QColor(168,200, 225));

    //绘制底部的圆
    QRectF tmpRect = QRectF(m_rect.bottomLeft(), QPointF(m_width, height()/2- m_width*m_radius));
    painter.fillRect(tmpRect, QColor(255, 0, 0));
    painter.setPen(Qt::NoPen);
    painter.setBrush(QColor(255, 0, 0));
    painter.drawEllipse(tmpRect.bottomLeft()+QPointF(tmpRect.width()/2, 0),m_width*m_radius, m_width*m_radius);
    painter.restore();

    //绘制刻度以及刻度值
    painter.save();
    painter.setPen(QColor(Qt::black));
    int nYCount = (maxValue - minValue)/10+1;
    qreal perHeight = (m_rect.height())/nYCount;
    for (int i=0; i<nYCount; ++i) {
        QPointF basePoint = m_rect.bottomLeft() - QPointF(0, perHeight/2) - QPointF(0, perHeight*i);
        //左侧大刻度
        painter.drawLine(basePoint, basePoint+QPointF(-10, 0));
        for (int j=1; j<10; ++j) {
            if(i == nYCount -1)
                continue;
            painter.drawLine(basePoint-QPointF(0, perHeight/10*j),basePoint-QPointF(5, perHeight/10*j));
        }
        painter.drawText(basePoint+QPointF(-28, 4), QString("%1").arg(minValue+i*10));
        //右侧大刻度
        basePoint = m_rect.bottomRight() - QPointF(0, perHeight/2) - QPointF(0, perHeight*i);
        painter.drawLine(basePoint, basePoint+QPointF(10, 0));
        for (int j=1; j<10; ++j) {
            if(i == nYCount -1)
                continue;
            painter.drawLine(basePoint-QPointF(0, perHeight/10*j),basePoint-QPointF(-5, perHeight/10*j));
        }
    }
    painter.restore();

    //根据值填充m_rect
    qreal h = (m_value-minValue)/(maxValue-minValue)*(m_rect.height()-perHeight);
    if(h<0)
        h = 0;
    if(h > m_rect.height())
        h = m_rect.height();
    painter.fillRect(m_rect.adjusted(0, m_rect.height()-h-perHeight/2-1 , 0, 0), QColor(255, 0, 0));

    QWidget::paintEvent(e);
}

void thermometreDlg::startAnimation()
{
    qreal startValue = getValue();
    m_valueAnimation->setKeyValueAt(0, startValue-1);
    m_valueAnimation->setKeyValueAt(0.5, curValue+1);
    m_valueAnimation->setKeyValueAt(1, curValue);
    m_valueAnimation->setStartValue(startValue-2);
    m_valueAnimation->start();
}

需要改变当前显示的值,只需要调用代码中的函数

void changeValue(qreal value);

3、效果图如下:

麻烦各位大佬给小弟点个赞!thanks

举报

相关推荐

0 条评论