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);
    }
}
相关推荐
卡卡~~15 分钟前
“101计划”核心课程实践教材《数据实验结构指导-C++语言版》题目集
开发语言·c++·学习·算法
qq_4069810328 分钟前
大白话rust系列09 函数调用两次有什么错?
开发语言·python·rust
学逆向的36 分钟前
C 多文件开发
c语言·开发语言·网络安全
布吉岛的石头1 小时前
Java 程序员第 50 阶段3:数据工程:预训练语料清洗与去重
java·开发语言·人工智能·深度学习·transformer
benchmark_cc1 小时前
QuantDash 安装成功后,如何验证 Python 环境可以正常导入 SDK?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
学逆向的1 小时前
C 内存属性
c语言·开发语言·算法·网络安全
lengxuenong1 小时前
树状数组 · 信息学学习手册1-求和3个模板
c++·学习·算法·青少年编程
ShineWinsu2 小时前
对于Qt:信号与槽的解析
c++·qt·gui·lambda·信号·信号与槽·槽函数
WL学习笔记3 小时前
使用string类
c++·后端·string类