• 《QT Creator快速入门》第十章:2D绘制(2)


    1、抗锯齿渲染

        由于历史原因,QRect::right()和QRect::bottom()的返回值会偏离矩形真实的右下角,推荐使用QRectF来代替QRect,或者使用x() + width()和y() + height()来确定QRect的右下角。

        默认情况下,绘制会产生锯齿,可以使用QPainter::setRenderHint(RenderHint hint, bool on = true)来打开抗锯齿渲染,其中hint指定渲染方式,如QPainter::Antialiasing。

        例如以下为关闭和打开QPainter::Antialiasing抗锯齿渲染的效果:

    void Widget::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);
        painter.drawRect(1, 2, 20, 10);
    
        QPainter painter(this);
        painter.drawLine(2, 7, 6, 1);
    }

        

    void Widget::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.drawRect(1, 2, 20, 10);
        
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.drawLine(2, 7, 6, 1);
    }

        

     2、坐标变换

        坐标变换有基本变换、窗口-视口变换。

        ①、基本变换

        平移坐标系统:QPainter::translate()
        旋转坐标系统:QPainter::rotate()
        缩放坐标系统:QPainter::scale()
        扭曲坐标系统:QPainter::shear()
        保存当前坐标系统:QPainter::save()
        恢复保存的坐标系统:QPainter::restore()

       下面为使用示例:

    void Widget::paintEvent(QPaintEvent * event)
    {
        QPainter painter(this);
        painter.fillRect(rect(), Qt::white);
    
        painter.setPen(QPen(Qt::red, 11));
        painter.drawLine(QPoint(5, 6), QPoint(100, 99));
    
        painter.translate(200, 150);//将坐标系统平移,使(200, 150)作为坐标原点
        //painter.translate(-200, -150);//这样可以还原原点为(0, 0)
        painter.setPen(QPen(Qt::darkBlue, 11));
        painter.setRenderHint(QPainter::Antialiasing);
        painter.drawLine(QPoint(5, 6), QPoint(100, 99));
    
        painter.save();//保存painter的当前状态
        painter.rotate(90);//将坐标系统顺时针旋转90度
        painter.setPen(QPen(Qt::cyan, 11));
        painter.drawLine(QPoint(5, 6), QPoint(100, 99));
        painter.restore();//恢复painter到以前的状态
    
        painter.fillRect(-50, -50, 100, 50, QBrush(Qt::darkGreen));
        painter.save();
        painter.scale(0.5, 0.4);//将坐标系统进行缩放,水平为0.5倍,垂直为0.4倍
        painter.fillRect(-50, -50, 100, 50, QBrush(Qt::yellow));
        painter.restore();
    
        painter.setPen(Qt::blue);
        painter.setBrush(Qt::darkYellow);
        painter.drawEllipse(QRect(60, -100, 50, 50));
        painter.save();
        painter.shear(1.5, -0.7);//将坐标系统进行扭曲
        painter.setBrush(Qt::darkGray);
        painter.drawEllipse(QRect(60, -100, 50, 50));
        painter.restore();
    }
    View Code

        

        连续进行多个坐标转换的时候使用QTransform会更高效,下面使用QTimer定时器和QTransform坐标转换,模拟了简单时钟显示:

    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
        QTimer* timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(update()));//信号和槽
        timer->start(1000);
    }
    
    void Widget::paintEvent(QPaintEvent * event)
    {
        static int angle = 0;
        angle += 10;
        if(angle == 360)
            angle = 0;
    
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);//抗锯齿
        int sideMin = qMin(width(), height());
    
        QTransform transform;
        transform.translate(width() / 2, height() / 2);//移动坐标原点至中心点
        transform.rotate(angle);//将坐标系统顺时针旋转, 每次增加10°
        transform.scale(sideMin / 300, sideMin / 300);//将坐标系统缩放,以适应窗口放大
        painter.setWorldTransform(transform);//进行坐标转换
    
        painter.drawEllipse(-120, -120, 240, 240);//画圆
        painter.drawLine(0, 0, 100, 0);//画指针
    }
    View Code

        

         ②、窗口-视口转换

        使用QPainter的绘制函数进行绘制的时候使用的是逻辑坐标,它们最后会被转换为绘图设备的物理坐标来进行绘制。窗口是指逻辑坐标下的一个矩形,视口是物理坐标下的一个矩形。

        QPainter::setWindow用来设置窗口的逻辑坐标,QPainter::setViewport用来设置视口物理坐标。

  • 相关阅读:
    20162309《程序设计与设计结构》第一周学习总结
    20162309《程序设计与数据结构》课程总结
    网络编程与安全实验报告
    四则运算挑战出题
    Android实验报告
    四则运算第二周实验报告
    XP实验报告
    20162319 2017-2018-1 《程序设计与数据结构》第3周学习总结
    20162319 2017-2018-1 《程序设计与数据结构》第1周学习总结
    结对编程-马尔克夫链
  • 原文地址:https://www.cnblogs.com/milanleon/p/7357901.html
Copyright © 2020-2023  润新知