用Qt编写温度计

2018-04-15 21:56:49  阅读 207 次 评论 1 条
先看看效果:

th.gif

作者:fearlazy,需要源码的可以加微信fearlazy_com发私信给我。


一、思路
该温度计的实现包含两个方面。其一是绘制,其二是动画。
绘制主要由背景、刻度值和中间的柱体三部分组成。

温度计最关键的属性是温度值,所以动画只要关联温度值属性即可。


二、实现关键点

1.首先我们需要一个类继承于QWidget,重写paintEvent事件以便于我们能够进行绘制操作。
2.定义一个温度值属性,并用Q_PROPERTY声明这个属性(动画绑定属性时需要),然后写属性的READ和WRITE对应的函数。

  Q_PROPERTY(qreal value READ getValue WRITE setValue)  //声明属性
  
  void setValue(qreal value); //设置值
  qreal getValue(); //获取值
  
  qreal               m_value; //温度值

3.定义一个动画变量,并绑定value属性(属性名与Q_PROPERTY声明的一致)。

   m_valueAnimation = new QPropertyAnimation(this,"value",this);
   m_valueAnimation->setDuration(1000); //动画时间1秒

   m_valueAnimation->setEasingCurve(QEasingCurve::OutCubic); //动画效果

4.绘制

根据大小计算中间柱子的矩形区域m_rect,其他内容的绘制将基于m_rect计算:

void CThermometer::updateRect()
{
       m_rect.setX((this->width() - m_width)/2);
       m_rect.setY(m_nPadTop);  //顶部预留
       m_rect.setWidth(m_width);
       
       //减去顶部和底部预留以及底部圆形的高度。
       m_rect.setHeight(this->height() - m_nPadTop - m_nPadBottom - CIRCLE_RADIUS*m_width);
}

接着按顺序绘制:
    //中心柱子底色
    painter.fillRect(m_rect,QColor(168,200,225));
    
    //圆-放置在m_rect的底部
    painter.save();
    QRectF tmpRect = QRectF(m_rect.bottomLeft(),QSizeF(m_width,m_width*CIRCLE_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*CIRCLE_RADIUS,m_width*CIRCLE_RADIUS);
    painter.restore();
   
   //画刻度-放置在m_rect的左右两侧
    painter.save();
    painter.setPen(m_scaleColor);
    int nYcount = (m_maxValue - m_minValue)/10 + 1; //分为几个大刻度(预留1个十度上下各0.5个)
    qreal perHeight = m_rect.height()/nYcount;
    int nPrecisionCount = 10/(int)m_precision;
    qreal precisionHeight = perHeight/nPrecisionCount; //最小刻度
    QFontMetricsF fMetrics(painter.font());
    for(int i = 0; i < nYcount; ++i)
    {
        //左侧刻度
        QPointF basePoint = m_rect.bottomLeft() + QPointF(0,-perHeight/2) + QPointF(-2,-perHeight*i);
        painter.drawLine(basePoint,basePoint + QPointF(-8,0)); //左侧大刻度
        if(i != nYcount - 1)
        {
            for(int j = 1; j < nPrecisionCount; ++j)
            {
                painter.drawLine(basePoint + QPointF(0,-precisionHeight*j),basePoint + QPointF(-5,-precisionHeight*j)); //左侧小刻度
            }
        }
        //刻度值
        QString text = QString::number(m_minValue + 10*i);
        QRectF textRect(basePoint + QPointF(-8,0),QSizeF(fMetrics.width(text),fMetrics.height()));
        textRect.adjust(-textRect.width() - 5,-textRect.height()/2,-textRect.width() - 5,-textRect.height()/2);
        painter.drawText(textRect,Qt::AlignCenter,text);
        //右侧刻度
        basePoint = m_rect.bottomRight() + QPointF(0,-perHeight/2) + QPointF(2,-perHeight*i);
        painter.drawLine(basePoint,basePoint + QPointF(8,0));
        if(i != nYcount - 1)
        {
            for(int j = 1; j < nPrecisionCount; ++j)
            {
                painter.drawLine(basePoint + QPointF(0,-precisionHeight*j),basePoint + QPointF(5,-precisionHeight*j)); //左侧小刻度
            }
        }
    }
    painter.restore();
    
    
    //值-根据m_value和最大最小值计算在m_rect中所占的百分数。
    qreal h = (m_value - m_minValue + 5)/(m_maxValue - m_minValue + 10)*m_rect.height();
    if(h < 0)
        h = 0;
        
    if(h > m_rect.height())
        h = m_rect.height();
        
    painter.fillRect(m_rect.adjusted(0,m_rect.height() - h,0,0),QColor(255,0,0));




本文地址:http://fearlazy.com/index.php/post/63.html
版权声明:本文为原创文章,版权归 fearlazy 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

评论列表

  1. 风中的蒲公英
    风中的蒲公英  @回复

    这效果可以,赞一下