做的比较炫的网站,开源企业网站管理系统,设计学习网站,深圳做网站哪个平台好文章目录 1 效果2 原理3 编码实践3.1 创建仪表属性类3.2 设置类属性3.3 绘制图案3.3.1 设置反走样3.3.2 绘制背景3.3.3 重新定义坐标原点3.3.4 绘制圆环3.3.5 绘制刻度线3.3.6 绘制刻度线上的描述值3.3.7 绘制指针3.3.8 绘制指针数值和单位3.3.9 控制指针变化 扩展福利参考 1 效… 文章目录 1 效果2 原理3 编码实践3.1 创建仪表属性类3.2 设置类属性3.3 绘制图案3.3.1 设置反走样3.3.2 绘制背景3.3.3 重新定义坐标原点3.3.4 绘制圆环3.3.5 绘制刻度线3.3.6 绘制刻度线上的描述值3.3.7 绘制指针3.3.8 绘制指针数值和单位3.3.9 控制指针变化 扩展福利参考 1 效果
下面仪表模拟的是转速表和速度表转速表中有怠速转速降功转速的逻辑。 下面是模拟双针仪表的效果 2 原理
1重写paintEvent进行仪表绘制使用QPropertyAnimation进行动画绘制
2进行属性动画绘制时需要使用Q_PROPERTY宏用于声明类的属性
3 编码实践
下面代码位调用方法接口的具体实现在后文中有详细描述。
发射的信号 //发送发动机转速void sendEngineSpeed(double);//发送大机速度值void sendTrainSpeedNum(short);创建仪表类并设置参数
//发动机转速表DashBoardWidget3 *dashBoardWidget5 new DashBoardWidget3(this);dashBoardWidget5-setScaleMajor(6);//6个大区间dashBoardWidget5-setScaleMinor(5);//每个区间5个小格dashBoardWidget5-setUnit();dashBoardWidget5-setText(RPMx100);dashBoardWidget5-setmax(30);dashBoardWidget5-setUnitDrawInterval(1);//每隔一个大区间画一个刻度线描述值dashBoardWidget5-setGeometry(750, 20, 300, 300);connect(this, MainInterface::sendEngineSpeed,dashBoardWidget5, DashBoardWidget3::valueChanged);//汽车速度表DashBoardWidget3 *dashBoardWidget6 new DashBoardWidget3(this);dashBoardWidget6-setScaleMajor(12);//大区间dashBoardWidget6-setScaleMinor(2);//每个区间的小值dashBoardWidget6-setUnit();dashBoardWidget6-setText(km/h);dashBoardWidget6-setmax(120);dashBoardWidget6-setUnitDrawInterval(2);// dashBoardWidget-move(600, 20);dashBoardWidget6-setGeometry(750, 300, 300, 300);connect(this, MainInterface::sendTrainSpeedNum,dashBoardWidget6, DashBoardWidget3::valueChanged);3.1 创建仪表属性类
struct DashBoardWidgetPrivate{//刻度值的最大值和最小值int maxValue 100;int minValue 0;//刻度值角度double startAngle -50;double endAngle 230;double value minValue;//大区间最小区间int scaleMajor 10;int scaleMinor 5;//单位和描述文字QString unit ;QString text ;//仪表颜色QColor arcColor QColor(56, 61, 74);//QColor(0, 128, 255);//刻度颜色QColor scaleColor QColor(71, 186, 252);//QColor(4, 168, 173);//指针颜色QColor pointerColor QColor(255, 0, 0);//文件颜色QColor textColor QColor(144, 133, 116);//背景颜色QColor backgroundColor Qt::transparent;//仪表指针1属性动画QPropertyAnimation *animation;};3.2 设置类属性 Q_PROPERTY(double value READ value WRITE setValue)Q_PROPERTY(double min READ min WRITE setMin)Q_PROPERTY(double max READ max WRITE setmax)Q_PROPERTY(double startAngle READ startAngle WRITE setStartAngle)Q_PROPERTY(double endAngle READ endAngle WRITE setEndAngle)Q_PROPERTY(int scaleMajor READ scaleMajor WRITE setScaleMajor)Q_PROPERTY(int scaleMinor READ scaleMinor WRITE setScaleMinor)Q_PROPERTY(QString unit READ unit WRITE setUnit)Q_PROPERTY(QString text READ text WRITE setText)Q_PROPERTY(QColor arcColor READ arcColor WRITE setArcColor)Q_PROPERTY(QColor scaleColor READ scaleColor WRITE setScaleColor)Q_PROPERTY(QColor pointerColor READ pointerColor WRITE setPointerColor)Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)创建对应的函数 QSize sizeHint() const override;QSize minimumSizeHint() const override;double value() const;void setValue(const double value);void setMin(const double min);double min() const;void setmax(const double max);double max() const;void setStartAngle(const double startAngle);double startAngle() const;void setEndAngle(const double endAngle);double endAngle() const;void setScaleMajor(const int scale);int scaleMajor() const;void setScaleMinor(const int scale);int scaleMinor() const;void setUnit(const QString unit);//设置单位QString unit() const;void setText(const QString text);//设置文字QString text() const;void setArcColor(const QColor color);QColor arcColor() const;void setScaleColor(const QColor color);QColor scaleColor() const;void setPointerColor(const QColor color);QColor pointerColor() const;void setTextColor(const QColor color);QColor textColor() const;void setBackgroundColor(const QColor color);QColor backgroundColor() const;3.3 绘制图案
在类绘制事件中添加各种绘制信息
void DashBoardWidget3::paintEvent(QPaintEvent *event){QWidget::paintEvent(event);QPainter painter(this);//....
}3.3.1 设置反走样
//反走样是图形学中的重要概念用以防止通常所说的“锯齿”现象的出现。很多系统的绘图 API 里面都内置了有关反走样的算法不过由于性能问题默认一般是关闭的painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);3.3.2 绘制背景 // 背景if (d-backgroundColor ! Qt::transparent) {painter.setPen(Qt::NoPen);painter.fillRect(rect(), d-backgroundColor);}3.3.3 重新定义坐标原点 // 平移中心painter.translate(width() / 2, height() / 2);调整之前
调整之后 3.3.4 绘制圆环 // 圆环drawArc(painter);实现函数
void DashBoardWidget3::drawArc(QPainter *painter)
{double min qMin(width(), height());double arcWidth min / 15.0;double radius min / 3 - arcWidth;QRectF rect QRectF(-radius, -radius, radius * 2, radius * 2);QPen pen;pen.setWidthF(arcWidth);pen.setCapStyle(Qt::FlatCap);// 圆弧背景double angle d-endAngle - d-startAngle;pen.setColor(d-arcColor);painter-setPen(pen);painter-drawArc(rect, d-startAngle * 16, angle * 16);
}绘制效果如下 3.3.5 绘制刻度线 // 刻度线drawScale(painter);实现函数
void DashBoardWidget3::drawScale(QPainter *painter)
{painter-save();painter-rotate(270 - d-endAngle);int steps (d-scaleMajor * d-scaleMinor);//区间*每个区间的小刻度double angleStep (d-endAngle - d-startAngle) / steps;double min qMin(width(), height());double radius min / 3;QPen pen(d-scaleColor);pen.setCapStyle(Qt::RoundCap);for (int i 0; i steps; i) {if (i % d-scaleMinor 0) {//画大刻度pen.setWidthF(1.5);painter-setPen(pen);painter-drawLine(0, radius - 8, 0, radius 5);//画刻度线长度}else{//画小刻度pen.setWidthF(0.5);painter-setPen(pen);painter-drawLine(0, radius - 8, 0, radius - 3);}painter-rotate(angleStep);}painter-restore();
}效果如下 3.3.6 绘制刻度线上的描述值 // 刻度线上的描述值drawScaleNum(painter);实现函数
//画刻度线上的说明值
void DashBoardWidget3::drawScaleNum(QPainter *painter)
{painter-save();painter-setPen(d-scaleColor);double min qMin(width(), height());double radius min / 2.4;//半径QFont font(Microsoft YaHei, min / 25);painter-setFont(font);double startRad d-endAngle * (M_PI / 180);//qDebug()startRad:startRad;double deltaRad (d-endAngle - d-startAngle) * (M_PI / 180) / d-scaleMajor;QFontMetrics fontMetrics(font);if(m_unitDrawInterval d-scaleMajor){m_unitDrawInterval d-scaleMajor;}for (int i 0; i d-scaleMajor; i m_unitDrawInterval) {//每个大区间都要画刻度值double sina qSin(startRad - i * deltaRad);double cosa qCos(startRad - i * deltaRad);double value 1.0 * i * ((d-maxValue - d-minValue) / d-scaleMajor) d-minValue;// 1.0 * 1 *((1200 -0)/10) 0// qDebug()d-maxValue:d-maxValue;//qDebug()d-minValue:d-minValue;//qDebug()value:value;QString strValue QString(%1).arg(value);double textWidth fontMetrics.horizontalAdvance(strValue);double textHeight fontMetrics.height();int x radius * cosa - textWidth / 2;int y -radius * sina textHeight / 4;painter-drawText(x, y, strValue);}painter-restore();
}
效果如下 3.3.7 绘制指针 // 指示器(指针)drawPointer(painter);实现函数
//画指针
void DashBoardWidget3::drawPointer(QPainter *painter)
{painter-save();painter-setPen(Qt::NoPen);painter-setBrush(d-pointerColor);//设置画笔颜色double radius qMin(width(), height()) / 3.0;QPolygonF pts;pts QPointF(-5, 0) QPointF(0, -8) QPointF(5, 0) QPointF(0, radius);painter-rotate(270 - d-endAngle);double degRotate (d-endAngle - d-startAngle) / (d-maxValue - d-minValue) * (d-value - d-minValue);painter-rotate(degRotate);painter-drawConvexPolygon(pts);painter-restore();
}效果如下 3.3.8 绘制指针数值和单位 // 显示指针数值和单位drawValue(painter);实现函数
//画数值和单位
void DashBoardWidget3::drawValue(QPainter *painter)
{painter-save();painter-setPen(d-textColor);double min qMin(width(), height());double radius min / 2.0 - min / 4.8;QFont font(Microsoft YaHei, min / 25);painter-setFont(font);//绘制指针数值和单位QString strValue QString(%1 %2).arg(d-value).arg(d-unit);QRectF valueRect(-radius, radius / 2.5, radius * 2, radius / 3.5);QColor pointerColor QColor(0, 0, 0);painter-setBrush(pointerColor);//设置颜色painter-setPen(QPen(QColor(0, 0, 0)));painter-drawText(valueRect, Qt::AlignCenter, strValue);//绘制描述文字QRectF text2Rect(-radius, radius / 1.5, radius * 2, radius / 2.5);painter-setPen(QPen(QColor(255, 0, 0)));//设置画笔颜色painter-setBrush(d-textColor);//设置画笔颜色font.setPixelSize(12);painter-setFont(font);painter-drawText(text2Rect, Qt::AlignCenter, d-text);painter-restore();
}实现效果 3.3.9 控制指针变化
signals:void valueChanged(const double value);DashBoardWidget3::DashBoardWidget3(QWidget *parent): QWidget(parent), d(new DashBoardWidgetPrivate)
{d-animation new QPropertyAnimation(this, value, this);setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);connect(this, DashBoardWidget3::valueChanged,this, DashBoardWidget3::onStartAnimation);}实现函数
//仪表指针变动的动画
void DashBoardWidget3::onStartAnimation(double value)
{if(value d-minValue|| value d-maxValue|| value d-value){}else{double start d-value;double end value;d-animation-setStartValue(start);d-animation-setEndValue(end);d-animation-start();}
}扩展
可以思考以下下面的效果如何实现 福利
完整的项目代码
欢迎各位start
参考
Qt自定义控件之仪表盘的完整实现