1 QPaint 绘图变换
qt存在坐标系,进行矩阵的变换得到对于的效果,如平移,旋转,缩放等功能,方便进行绘图。
图形的变换就是坐标系的转换。
1.1 变换函数
坐标变换
void QPainter::rotate(qreal angle) // 旋转,正值为顺时针
void QPainter::scale(qreal sx, qreal sy) // 横纵,缩放
void QPainter::shear(qreal sh, qreal sv) // 扭转
void QPainter::translate(const QPointF & offset) // 平移
状态保存
void QPainter::save() // 保存painter状态到栈上
void QPainter::restore() // 将栈中状态恢复到painter上
void QPainter::resetTransform() // 回退所有变换
1.2 实例
绘画一个五角星,并进行简单的图形变换。
代码示例
/// 重载widget的paintEvent
void paintEvent(QPaintEvent * event) Q_DECL_OVERRIDE;
void Widget::paintEvent(QPaintEvent *event)
{
QPen pen;
pen.setWidth(2);
pen.setColor(Qt::red);
pen.setStyle(Qt::SolidLine);
pen.setJoinStyle(Qt::RoundJoin);
QBrush brush;
brush.setColor(Qt::red);
brush.setStyle(Qt::SolidPattern);
QPainter painter(this);
painter.setPen(pen);
painter.setBrush(brush);
painter.setRenderHint(QPainter::TextAntialiasing,true);
painter.setRenderHint(QPainter::Antialiasing);
qreal r = 100;
qreal deg = 3.1415926/180; // 一度对应的弧度
qreal y_move = r/(2*cos(54*deg));
// 五角星的5个顶点, 参考上图计算的(),强制Y坐标减去 r/(2*cos(54*deg)), 将原点移至中心点
// 由于widget的坐标系为左上角为原点,向右为X正,向下为Y正,计算出的这个坐标,在widget中是画不全的。
QPoint points[5] = {
QPoint(r/2, 0 - y_move), // 0
QPoint(r/2+r*std::cos(72*deg), r*sin(72*deg)- y_move), // 1
QPoint(0, r/2*std::tan(72*deg)- y_move), // 2
QPoint(-r/2-r*cos(72*deg), r*sin(72*deg)- y_move), // 3
QPoint(-r/2, 0 - y_move), // 4
};
int w = this->width();
int h = this->height();
// 使用路径进行绘画
QPainterPath path;
path.moveTo(points[0]);
path.lineTo(points[2]);
path.lineTo(points[4]);
path.lineTo(points[1]);
path.lineTo(points[3]);
path.lineTo(points[0]);
path.closeSubpath();
QFont font;
font.setPointSize(12);
// 每个顶点添加一个文本
path.addText(points[0], font, "0");
path.addText(points[1], font, "1");
path.addText(points[2], font, "2");
path.addText(points[3], font, "3");
path.addText(points[4], font, "4");
// 平移至widget中心
painter.translate(w/2, h/2);
QPoint text_point(0, 0);
// 保存状态,然后进行变换
painter.save();
painter.setFont(font);
painter.drawPath(path);
painter.drawText(text_point,"S1");
// 恢复到之前保持的状态,并进行变换
painter.restore();
painter.setFont(font);
painter.translate(-200, 0); // 注意这个变换,是基于上次save的变换
painter.shear(0.5, 0); // 扭曲
painter.drawPath(path);
painter.drawText(text_point,"S2");
// 恢复到原始状态
painter.resetTransform();
painter.setFont(font);
painter.translate(w/2+200, h/2); // 注意这个变换,是基于最原始的变换(也就是计算出的坐标)
painter.rotate(70); // 旋转
painter.scale(0.8, 0.8); // 缩放
painter.drawPath(path);
painter.drawText(text_point,"S3");
}