QT绘图 QPainter 绘图变换

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");
}
运行结果

程序结果

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值