在Qt绘图中,经常需要绘制一些仪表的刻度盘,我们知道,仪表刻度上的数据基本呈现环绕模式,那么如何在Qt中实现这种绘图效果呢???
在Qt 绘图类QPainter中,提供了rotate()和translate()方法,在绘图过程中通过这两个方法的配置使用,完全可以实现刻度的环绕。下面是本人写的一个例子,比较简单。
- 头文件widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPainter>
#include <QResizeEvent>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = Q_NULLPTR);
virtual ~Widget() override;
protected:
virtual void paintEvent(QPaintEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
protected:
QPointF trans(int i);
private:
QPointF m_centerPoint;
qreal m_nRadius;
};
#endif // WIDGET_H
- 源文件widget.cpp
#include "widget.h"
#include <QtMath>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
m_centerPoint = QPointF(width()/2, height()/2);
m_nRadius = (height() - 50)/2;
}
Widget::~Widget()
{
}
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing,true);
painter.fillRect(this->rect(), Qt::GlobalColor::black);
/******************************************************************/
painter.setPen(Qt::white);
painter.drawEllipse(m_centerPoint,m_nRadius,m_nRadius);
//画刻度
QPen &pen = const_cast<QPen&>(painter.pen());
pen.setStyle(Qt::DotLine);
painter.setPen(pen);
QFontMetrics mit(painter.font());
for(int i = 30 ;i <= 360; i+= 30)
{
QPointF pt = trans(i);
painter.drawLine(m_centerPoint, pt);
QString strText = QString::number(i); //设置当前字体
painter.save();
QSize nSize= mit.size( Qt::TextSingleLine , strText);
//【1】偏移坐标原点到需要绘制刻度的位置
painter.translate(pt);
//【2】旋转指定的角度
painter.rotate(i);
//【3】 画刻度
painter.drawText(QPoint(-nSize.width()/2,-nSize.height()/2), strText);
painter.restore();
}
}
void Widget::resizeEvent(QResizeEvent *event)
{
//size 改变时,更新中心点
m_centerPoint.setX(event->size().width()/2);
m_centerPoint.setY(event->size().height()/2);
//size改变时,更新半径
m_nRadius = (event->size().height() - 50)/2;
}
/*
*函数功能:获取角度对应的圆弧点
*/
QPointF Widget::trans(int angle)
{
QPointF ptResult(m_centerPoint);
//[角度转弧度]
float rad = qDegreesToRadians(static_cast<float>(angle));
ptResult.setX(m_centerPoint.x() + m_nRadius * qSin(static_cast<qreal>(rad)));
ptResult.setY(m_centerPoint.y() - m_nRadius * qCos(static_cast<qreal>(rad)));
return ptResult;
}
- 运行结果