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);
    }
}
相关推荐
汉克老师16 分钟前
GESP5级C++考试语法知识(七、链表(二)双链表)
c++·链表·双链表·gesp5级·gesp五级
旖-旎16 分钟前
二分查找(寻找旋转排序数组中的最小值)(7)
c++·算法·二分查找·力扣
C羊驼18 分钟前
C/C++数据结构与算法:穷举法
c语言·c++·笔记·学习·算法
十五年专注C++开发21 分钟前
libuv:一个跨平台的C++异步 I/O 库
开发语言·c++·node.js·libuv·vlibuv
SuperEugene25 分钟前
前端 console 日志规范实战:高效调试 / 垃圾 log 清理与线上安全避坑|编码语法规范篇
开发语言·前端·javascript·vue.js·安全
程序员敲代码吗25 分钟前
USB-C接口深度测试:从Vconn到电压的全方位分析
c语言·开发语言
racerun34 分钟前
跳转链接批量解析工具 python
开发语言·python
qq_417695051 小时前
C++中的解释器模式
开发语言·c++·算法
pingan87871 小时前
试试 docx.js 一键生成 Word 文档,效果很不错
开发语言·前端·javascript·ecmascript·word
xiaoye-duck1 小时前
《算法题讲解指南:动态规划算法--路径问题》--9.最小路径和,10.地下城游戏
c++·算法·动态规划