温度计"/>
用Qt编写温度计
文章可能被更新,最新地址:.php/post/63.html
先看看效果:
一、思路
该温度计的实现包含两个方面。其一是绘制,其二是动画。
绘制主要由背景、刻度值和中间的柱体三部分组成。
温度计最关键的属性是温度值,所以动画只要关联温度值属性即可。
二、实现关键点
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));
作者:fearlazy
更多推荐
用Qt编写温度计
发布评论