0
点赞
收藏
分享

微信扫一扫

Qt 通过 QPainter 绘制坐标轴

young_d807 2022-01-12 阅读 259

一、概述

在自定义贝塞尔曲线中想绘制一个坐标轴。

二、步骤

2.1 新建一个类 PaintAxis 继承 QWidget

然后在界面上拖拽一个 widget,右键 widget 提升为 PaintAxis 。

2.2 重写 paintEvent 函数

  1. 绘制 x,y 轴线
  2. 绘制坐标刻度
  3. 绘制坐标值

三、代码

3.1 .h 文件

#ifndef PAINTAXIS_H
#define PAINTAXIS_H

#include <QWidget>
#include <QPainter>
#include <QDebug>

// @class 绘制坐标轴
// ----------------------------
class PaintAxis: public QWidget
{
public:
    PaintAxis(QWidget *parent);

    virtual void paintEvent(QPaintEvent *event);

    /// @brief 设置为数学坐标系
    void SetMathCoordinate(QPainter* painter);

    /// @brief 恢复默认坐标系
    void ResetDefaultCoordinate(QPainter* painter);

    /// void 绘制坐标刻度
    void PaintCoordinateCalibration(QPainter* painter);

    /// void 绘制坐标值
    void PaintCoordinateValue(QPainter* painter);

    /// void 绘制两条坐标轴直线
    void PaintCoordinateAxis(QPainter* painter);

private:
    QPoint m_ptStartPos; // 起始点
    int m_axisWidth;    // 坐标轴的宽度
    int m_axisHeight;   // 坐标轴的高度
};

#endif // PAINTAXIS_H

3.2 cpp 文件

#include "paintaxis.h"

const int GRAPH_SCALE = 2;                // 图的放大倍数
const int COORDINATE_CALIBRATION_LENGTH = 4;    // 坐标刻度的长度

// ----------------------------------------------------
PaintAxis::PaintAxis(QWidget *parent) : QWidget(parent)
{
    m_ptStartPos.setX(30);
    m_ptStartPos.setY(30);
    m_axisWidth = 256 * GRAPH_SCALE;
    m_axisHeight = 256 * GRAPH_SCALE;
}

// -------------------------------------------------
void PaintAxis::SetMathCoordinate(QPainter* painter)
{
    /*
     * @brief 转换为数学坐标系,原点在左下角
     */
    painter->setWindow(0,height(),width(),-height());
}

// ------------------------------------------------------
void PaintAxis::ResetDefaultCoordinate(QPainter* painter)
{
    /*
     * @brief 恢复默认坐标系,原点在左上角
     */
    painter->setWindow(0, 0, this->width(), this->height());
}

// ---------------------------------------------------
void PaintAxis::PaintCoordinateAxis(QPainter* painter)
{
    // 绘制 x 轴,y轴
    QPen pen;
    pen.setColor(Qt::white);
    painter->setPen(pen);
    SetMathCoordinate(painter);
    QPoint axisStartPoint;
    QPoint axisXEndPoint; // x 轴终点
    QPoint axisYEndPoint; // y 轴终点

    axisStartPoint.setX(m_ptStartPos.x());
    axisStartPoint.setY(m_ptStartPos.y());

    axisXEndPoint.setX(m_ptStartPos.x() + m_axisWidth);
    axisXEndPoint.setY(m_ptStartPos.y());

    axisYEndPoint.setX(m_ptStartPos.x());
    axisYEndPoint.setY(m_ptStartPos.y() + m_axisHeight);

    painter->drawLine(axisStartPoint, axisXEndPoint);
    painter->drawLine(axisStartPoint, axisYEndPoint);
}

// -----------------------------------------------------------
void PaintAxis::PaintCoordinateCalibration(QPainter* painter)
{
    /*
     * @brief 绘制坐标刻度
     */

    int deltaX = m_axisWidth / 16;  // X 轴坐标刻度宽度
    int deltaY = m_axisHeight / 16; // Y 轴坐标刻度宽度

    for (int i = m_ptStartPos.x(); i < m_axisWidth + m_ptStartPos.x(); )
    {
       // 横坐标位置每次递增
       i = i + deltaX;

       // 坐标刻度起始点
       QPoint calibrationStartPoint;
       calibrationStartPoint.setX(i);
       calibrationStartPoint.setY(m_ptStartPos.y());

       // 坐标刻度结束点
       QPoint calibrationEndPoint;
       calibrationEndPoint.setX(i);
       calibrationEndPoint.setY(m_ptStartPos.y() - COORDINATE_CALIBRATION_LENGTH);

       painter->drawLine(calibrationStartPoint, calibrationEndPoint);
     }

    for (int i = m_ptStartPos.y() + deltaY; i <= m_axisHeight + m_ptStartPos.y(); i = i + deltaY)
    {
       // 坐标刻度起始点
       QPoint calibrationStartPoint;
       calibrationStartPoint.setX(m_ptStartPos.x()); // x 轴不变,y 轴变
       calibrationStartPoint.setY(i);

       // 坐标刻度结束点
       QPoint calibrationEndPoint;
       calibrationEndPoint.setX(m_ptStartPos.x() - COORDINATE_CALIBRATION_LENGTH);
       calibrationEndPoint.setY(i);

       painter->drawLine(calibrationStartPoint, calibrationEndPoint);
     }
}

// ----------------------------------------------------
void PaintAxis::PaintCoordinateValue(QPainter* painter)
{
    /*
     * @brief 绘制坐标值
     */
    int axisXValue = 0;
    int axisYValue = 0;

    int deltaX = m_axisWidth / 16;  // X 轴坐标刻度宽度
    int deltaY = m_axisHeight / 16; // Y 轴坐标刻度宽度

    ResetDefaultCoordinate(painter); // 必须恢复原来的坐标系,不然文字会镜像

    for (int i = m_ptStartPos.x(); i <= m_axisWidth + m_ptStartPos.x(); )
    {
        i = i + deltaX;
        QString strAxisXValue = QString::number(axisXValue);
        QPoint temp;
        temp.setX(i - m_ptStartPos.x() - 10); // 左边移动的偏移量
        temp.setY(height() + 18 - m_ptStartPos.y());
        painter->drawText(temp, strAxisXValue);
        axisXValue = axisXValue + 16;
    }

    for (int i = 0; i <= m_axisHeight; i = i + deltaY)
    {
        QString strAxisYValue = QString::number(axisYValue);

        QPoint temp;
        temp.setX(m_ptStartPos.x() - 23);         // 左边移动的偏移量
        temp.setY(height() - m_ptStartPos.y() - i + 3);

        painter->drawText(temp, strAxisYValue);
        axisYValue = axisYValue + 16;
    }
}

// -------------------------------------------
void PaintAxis::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    
    // 绘制坐标轴两条直线
    PaintCoordinateAxis(&painter);

    // 绘制坐标刻度
    PaintCoordinateCalibration(&painter);

    // 绘制坐标值
    PaintCoordinateValue(&painter);
}

四、结果

在这里插入图片描述

举报

相关推荐

0 条评论