字首

之前总共花了几天时间完成了QPainter类参考文件的翻译,如果公欲想做好那件事,首先要利用那个机构。

既然我们已经把准备工作做完了,那就绘制几个小控件试试手,刚好可以丰富一下我们的组件库。先来看一下实现效果:

样式1:

样式代码:

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

样式2:

样式代码:

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

样式3:

样式代码:

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

样式4:

样式代码:

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

换一个指针样式:

实现方法

#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);
(QPainter::Antialiasing); //开启反锯齿
(this->width() / 2, this->height() / 2); //将坐标原点平移到到窗口正中心

//等比例缩放,保证m_nRadius不变的情况下,圆的大小随窗口的大小自适应
int nSideLen = qMin(this->width(), this->height()); //获取较短边的边长,外圆直径就等于较短边边长
(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 = (in(strNumber);
int h = (in();
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 = (in(strNumber);
int h = (in();
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 = (in(strUnit);
h = (in();
x = 0 - w / 2;
y = 55 + h / 4;
painter->drawText(QPointF(x, y), strUnit);

painter->restore();
}

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

相关推荐