坐标转换函数
注意:变换的是坐标系统
| 分组 | 函数原型 | 功能说明 |
|---|---|---|
| 坐标变换 | 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);
}
}

