画奔驰c级的赛车(光说不练假把式)(1)

前言

前面一共花了几天的时间完成了QPainter类参考文档的翻译,工欲善其事,必先利其器。既然我们已经把准备工作做完了,那就绘制几个小控件试试手,刚好可以丰富一下我们的组件库。先来看一下实现效果:

样式1:

画奔驰c级的赛车(光说不练假把式)(2)

样式代码:

setBackgroundColor(QColor(20, 20, 20)); //背景 setFontColor(QColor(255, 255, 255)); //文字 setScaleColor(QColor(255, 255, 255)); //刻度 setIndicatorColor(QColor(255, 255, 255)); //指针

样式2:

画奔驰c级的赛车(光说不练假把式)(3)

样式代码:

setBackgroundColor(Qt::black); setFontColor(Qt::green); setScaleColor(QColor(255, 85, 0)); setIndicatorColor(QColor(0, 0, 255));

样式3:

画奔驰c级的赛车(光说不练假把式)(4)

样式代码:

setBackgroundColor(QColor(255, 85, 0)); setFontColor(Qt::black); setScaleColor(Qt::yellon); setIndicatorColor(Qt::green);

样式4:

画奔驰c级的赛车(光说不练假把式)(5)

样式代码:

setBackgroundColor(QColor(175, 255, 175)); setFontColor(QColor(255, 85, 0)); setScaleColor(QColor(128, 0, 128)); setIndicatorColor(QColor(255, 175, 175));

换一个指针样式:

画奔驰c级的赛车(光说不练假把式)(6)

实现方法

#ifndef DASHBOARD_H #define DASHBOARD_H #include <QWidget> #include <QTimerEvent> #define SIDE_LENGTH 200 #define ZH_CN(x) QString::fromLocal8Bit(x) #define SCALE_NUM 28 //0-28总共29个刻度 //仪表盘类 class Dashboard : public QWidget { Q_OBJECT public: Dashboard(QWidget *parent = 0); ~Dashboard(); void paintEvent(QPaintEvent *event); void drawBackground(QPainter *painter); void drawScale(QPainter *painter); void drawNumber(QPainter *painter); void drawIndicator(QPainter *painter); void drawText(QPainter *painter); void timerEvent(QTimerEvent *event); void setBackgroundColor(QColor color); void setFontColor(QColor color); void setScaleColor(QColor color); void setIndicatorColor(QColor color); public slots: void speedChanged(int nSpeed); private: int m_nRadius; //外圆半径 int m_nStartAngle; //起始角度 int m_nSpeed; //速度 QColor m_BackgroundColor; //背景颜色 QColor m_FontColor; //字体颜色 QColor m_ScaleColor; //刻度颜色 QColor m_IndicatorColor; //指针颜色 int m_nTimerId; //定时器Id bool m_bAdd; //模拟数据使用 }; #endif // DASHBOARD_H

重绘无非就是重写paintEvent()函数,也必须在这里,这一点之前的文档里面也说得很清楚了。

//重写绘制函数 void Dashboard::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); //开启反锯齿 painter.translate(this->width() / 2, this->height() / 2); //将坐标原点平移到到窗口正中心 //等比例缩放,保证m_nRadius不变的情况下,圆的大小随窗口的大小自适应 int nSideLen = qMin(this->width(), this->height()); //获取较短边的边长,外圆直径就等于较短边边长 painter.scale(nSideLen / (SIDE_LENGTH * 1.0), nSideLen / (SIDE_LENGTH * 1.0)); drawBackground(&painter); //绘制背景 drawScale(&painter); //绘制刻度 drawNumber(&painter); //绘制数字 drawIndicator(&painter); //绘制指针 drawText(&painter); //绘制文本 }

//绘制背景 void Dashboard::drawBackground(QPainter *painter) { painter->save(); painter->setPen(Qt::NoPen); //不绘制边框 //绘制外圆 painter->setBrush(m_BackgroundColor); painter->drawEllipse(QPointF(0, 0), m_nRadius, m_nRadius); painter->restore(); } //绘制刻度 void Dashboard::drawScale(QPainter *painter) { double dbLineWidth = 1.0; painter->save(); painter->rotate(m_nStartAngle); double dbRotate = (double)(360 - (m_nStartAngle * 2)) / (SCALE_NUM * 5); for (int i = 0; i <= SCALE_NUM * 5; i ) { painter->setPen(QPen(m_ScaleColor, dbLineWidth)); if (i % 5 == 0) //绘制大刻度 painter->drawLine(QPointF(0, m_nRadius), QPointF(0, m_nRadius * 0.9)); else //绘制小刻度 painter->drawLine(QPointF(0, m_nRadius), QPointF(0, m_nRadius * 0.95)); painter->rotate(dbRotate); } painter->restore(); } //绘制数字 void Dashboard::drawNumber(QPainter *painter) { painter->save(); int nRadius = (int)(m_nRadius * 0.78); painter->setFont(QFont("Arial", 10)); painter->setPen(QPen(m_FontColor)); QFontMetricsF fm = QFontMetricsF(painter->font()); double dbRotate = (double)(360 - (m_nStartAngle * 2)) / (SCALE_NUM * 5); for (int i=0; i<=SCALE_NUM * 5; i ) { if (i % 10 == 0) { int nAngle = 90 m_nStartAngle dbRotate * i; float fAngleArc = (nAngle % 360) * M_PI / 180; int x = nRadius * cos(fAngleArc); int y = nRadius * sin(fAngleArc); QString strNumber = QString::number(i * 2); int w = (int)fm.width(strNumber); int h = (int)fm.height(); x = x - w / 2; y = y h / 4; painter->drawText(QPointF(x, y), strNumber); } } painter->restore(); } //绘制指针 void Dashboard::drawIndicator(QPainter *painter) { painter->save(); QPolygon polygon; int nRadius = m_nRadius * 0.9; polygon << QPoint(-3, 0) << QPoint(3, 0) << QPoint(0, nRadius); double dbRotate = (double)(360 - (m_nStartAngle * 2)) / (SCALE_NUM * 5); dbRotate = dbRotate * (m_nSpeed / 2) m_nStartAngle; //画指针 painter->rotate(dbRotate); painter->setPen(Qt::NoPen); painter->setBrush(m_IndicatorColor); painter->drawConvexPolygon(polygon); painter->restore(); // 画中心圆圈 painter->save(); painter->setPen(Qt::NoPen); painter->setBrush(m_IndicatorColor); painter->drawEllipse(QPointF(0, 0), 7, 7); painter->restore(); } //绘制文本 void Dashboard::drawText(QPainter *painter) { painter->save(); painter->setFont(QFont("Arial", 20, QFont::Bold)); painter->setPen(QPen(m_FontColor)); QFontMetricsF fm = QFontMetricsF(painter->font()); //绘制速度 QString strNumber = QString::number(m_nSpeed); int w = (int)fm.width(strNumber); int h = (int)fm.height(); int x = 0 - w / 2; int y = 30 h / 4; painter->drawText(QPointF(x, y), strNumber); //绘制单位 painter->setFont(QFont("Arial", 10)); fm = QFontMetricsF(painter->font()); QString strUnit = "km/h"; w = (int)fm.width(strUnit); h = (int)fm.height(); x = 0 - w / 2; y = 55 h / 4; painter->drawText(QPointF(x, y), strUnit); painter->restore(); }

其他接口函数无非就是赋值操作,大家自行实现,这里就不贴代码了,觉得还有点意思的朋友,点个关注,点个赞支持一下。

画奔驰c级的赛车(光说不练假把式)(7)

,