Qt:QPainter坐标系统和坐标转换

坐标转换函数

注意:变换的是坐标系统

分组 函数原型 功能说明
坐标变换 void translate(qreal dx, qreal dy) 坐标系统平移一定的偏移量,坐标原点平移到新的点
坐标变换 void rotate(qreal angle) 坐标系统顺时针旋转一个角度
坐标变换 void scale(qreal sx, qreal sy) 坐标系统缩放
坐标变换 void shear(qreal sh, qreal sv) 坐标系统做扭转变换
状态保存与恢复 void save() 保存 painter 当前的状态,就是将当前状态压入堆栈
状态保存与恢复 void restore() 恢复上一次状态,就是从堆栈中弹出上次的状态
状态保存与恢复 void resetTransform() 复位所有的坐标变换
cpp 复制代码
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::TextAntialiasing);

    // 生成五角星的5个顶点坐标,假设原点在五角星中心
    qreal R = 100;  // 半径
    const qreal Pi = 3.14159;
    qreal deg = Pi * 72 / 180;
    QPoint points[5] = {
        QPoint(R, 0),
        QPoint(R * qCos(deg), -R *qSin(deg)),
        QPoint(R * qCos(2 * deg), -R * qSin(2 * deg)),
        QPoint(R * qCos(3 * deg), -R * qSin(3 * deg)),
        QPoint(R * qCos(4 * deg), -R * qSin(4 * deg))
    };
    // 设置字体
    QFont font;
    font.setPointSize(12);
    font.setBold(true);
    painter.setFont(font);
    // 设置画笔
    QPen penLine;
    penLine.setWidth(2);
    penLine.setColor(Qt::blue);
    penLine.setStyle(Qt::SolidLine);
    penLine.setCapStyle(Qt::FlatCap);
    penLine.setJoinStyle(Qt::BevelJoin);
    painter.setPen(penLine);

    // 设置画刷
    QBrush brush;
    brush.setColor(Qt::yellow);
    brush.setStyle(Qt::SolidPattern);
    painter.setBrush(brush);
    // 设置绘制五角星的PainterPath,以便重复使用
    QPainterPath starPath;
    starPath.moveTo(points[0]);
    starPath.lineTo(points[2]);
    starPath.lineTo(points[4]);
    starPath.lineTo(points[1]);
    starPath.lineTo(points[3]);
    starPath.closeSubpath();    // 闭合路径,最后一个点与第一个点相连


    // 绘图
    painter.save();
    painter.translate(100, 100);    // 平移坐标系统
    painter.drawPath(starPath);     // 画星星
    painter.drawText(0, 0, "S1");

    // 恢复坐标状态
    painter.restore();

    painter.translate(300, 120);
    painter.scale(0.8, 0.8);
    painter.rotate(90);
    painter.drawPath(starPath);     // 画星星
    painter.drawText(0, 0, "S2");

    painter.resetTransform();
    painter.translate(500, 100);
    painter.rotate(-145);
    painter.drawPath(starPath);     // 画星星
    painter.drawText(0, 0, "S3");
}

视口和窗口

视口表示绘图设备的任意一个矩形区域的物理坐标,可以只选取物理坐标的一个矩形区域用于绘图。默认情况下,视口等于绘图设备的整个矩形区。

窗口与视口是同一个矩形,只不过用逻辑坐标定义的坐标系。窗口可以直接定义矩形区的逻辑坐标范围。

视口就是画布的大小,窗口就是用的逻辑坐标系,我们使用逻辑坐标进行计算,这样进行绘制的图像就不会随着窗体宽高的变化而变形。

cpp 复制代码
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::TextAntialiasing);

    int W = width();
    int H = height();
    int side = qMin(W, H);  // 取长和宽的较小值
    QRect rect((W - side) / 2, (H - side) / 2, side, side); // viewport矩形区
    painter.drawRect(rect); // viewport的矩形区域
    painter.setViewport(rect);
    painter.setWindow(-100, -100, 200, 200);    // 设置窗口大小,逻辑坐标

    // 设置画笔
    QPen pen;
    pen.setWidth(1);
    pen.setColor(Qt::red);
    pen.setStyle(Qt::SolidLine);
    painter.setPen(pen);
    for(int i = 0; i < 36; ++i) {
        painter.drawEllipse(QPoint(50.0, 0), 50, 50);
        painter.rotate(10);
    }
}
相关推荐
阿里嘎多学长1 小时前
2026-04-30 GitHub 热点项目精选
开发语言·程序员·github·代码托管
j_xxx404_3 小时前
Linux:静态链接与动态链接深度解析
linux·运维·服务器·c++·人工智能
叶小鸡3 小时前
Java 篇-项目实战-苍穹外卖-笔记汇总
java·开发语言·笔记
AI人工智能+电脑小能手3 小时前
【大白话说Java面试题】【Java基础篇】第22题:HashMap 和 HashSet 有哪些区别
java·开发语言·哈希算法·散列表·hash
c++之路4 小时前
C++23概述
java·c++·c++23
时空系4 小时前
第10篇:继承扩展——面向对象编程进阶 python中文编程
开发语言·python·ai编程
CHANG_THE_WORLD5 小时前
python 批量终止进程exe
开发语言·python
古城小栈5 小时前
从 cargo-whero 库中,找到提升 rust 的契机
开发语言·后端·rust
学涯乐码堂主5 小时前
有趣的“打擂台算法”
c++·算法·青少年编程·gesp
云栖梦泽6 小时前
Linux内核与驱动:14.SPI子系统
linux·运维·服务器·c++