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);
    }
}
相关推荐
会编程的土豆几秒前
【数据结构与算法】再次全面了解LCS底层
开发语言·数据结构·c++·算法
低频电磁之道3 分钟前
解决 Windows C++ DLL 导出类不可见的编译错误
c++·windows
jerryinwuhan11 分钟前
RDD第二次练习
开发语言·c#
wechat_Neal13 分钟前
Golang的车载应用场景
开发语言·后端·golang
weixin_513449961 小时前
walk_these_ways项目学习记录第八篇(通过行为多样性 (MoB) 实现地形泛化)--策略网络
开发语言·人工智能·python·学习
飞Link1 小时前
逆向兼容的桥梁:3to2 自动化降级工具实现全解析
运维·开发语言·python·自动化
曾阿伦1 小时前
Python3 文件 (夹) 操作备忘录
开发语言·python
dong__csdn1 小时前
jdk添加信任证书
java·开发语言
君义_noip2 小时前
信息学奥赛一本通 4150:【GESP2509七级】⾦币收集 | 洛谷 P14078 [GESP202509 七级] 金币收集
c++·算法·gesp·信息学奥赛·csp-s
Ricky_Theseus2 小时前
静态链接与动态链接
c++