• 窗口-视口转换(详细)


    在QPainter中,绘制图像使用逻辑坐标绘制,然后再转化为绘图设备的物理坐标。

    • 窗口(window):表示逻辑坐标下的相同矩形
    • 视口(viewport):表示物理坐标下的指定的一个任意矩形

    默认情况:逻辑坐标和物理坐标是重合的。

    setWindow()

    设置逻辑坐标
    setViewPort()设置物理坐标

    保存状态和返回状态:

    save()保存当前的状态
    restore()返回上一个状态

     例子:

    1. void Widget::paintEvent(QPaintEvent *event)
    2. {
    3. QPainter painter(this);
    4. QPen pen(Qt::black);
    5. pen.setCapStyle(Qt::RoundCap);//笔帽的样式
    6. pen.setJoinStyle(Qt::RoundJoin);//连接的样式
    7. pen.setWidth(10);
    8. painter.setBrush(Qt::black);
    9. painter.setPen(pen);//设置笔
    10. painter.save();//保存当前设置
    11. painter.drawRect(0,0,100,100);
    12. QPen pen1(Qt::cyan);
    13. pen1.setCapStyle(Qt::FlatCap);//笔帽的样式
    14. pen1.setJoinStyle(Qt::BevelJoin);//连接的样式
    15. pen1.setWidth(10);
    16. painter.setBrush(Qt::cyan);
    17. painter.setPen(pen1);//设置笔
    18. painter.drawRect(100,100,100,100);
    19. painter.restore();//返回上一个设置
    20. painter.drawRect(200,200,100,100);
    21. }

     窗口和视口的分析和使用:

    初始窗口和视口的大小:

    • 初始状态下:窗口和视口的大小相同,相当于窗口的大小
    • 可以修改窗口大小(在构造函数中resize())

    窗口的初始大小: 

    1. void Widget::paintEvent(QPaintEvent *event)
    2. {
    3. QPainter painter(this);
    4. painter.setPen(Qt::cyan);
    5. painter.setBrush(Qt::blue);
    6. qDebug()<<"视口的宽度="<<painter.viewport().width()<<"视口的高度="<<painter.viewport().height();
    7. qDebug()<<"窗口的宽度="<<painter.window().width()<<"窗口的高度="<<painter.window().height();
    8. }

    修改窗口大小:

     在构造函数中使用resize()函数

    1. Widget::Widget(QWidget *parent)
    2. : QWidget(parent)
    3. , ui(new Ui::Widget)
    4. {
    5. ui->setupUi(this);
    6. resize(400,400);
    7. }

     再次运行:

    只修改视口 

    只修改视口时,相当于对绘制的图形进行缩放。

    • setViewport() 的宽度和高度大于初始视口的宽度和深度,相当于放大
    • setViewport() 的宽度和高度小于初始视口的宽度和深度,相当于缩小

    放大或缩小倍数为:  

    • 宽度的倍数:  现视口宽度/初始视口宽度
    • 高度的倍数:  现视口高度/初始视口高度

    起始点为:setViewport() 设置的起始点,例如 setViewport(50,50,100,100)

    • 把(0,0)位置放到 (50,50)上

    当 setViewport()的起始坐标为(0,0)时

    1. Widget::Widget(QWidget *parent)
    2. : QWidget(parent)
    3. , ui(new Ui::Widget)
    4. {
    5. ui->setupUi(this);
    6. resize(400,400);
    7. }
    8. void Widget::paintEvent(QPaintEvent *event)
    9. {
    10. QPainter painter(this);
    11. painter.setPen(Qt::cyan);
    12. painter.drawRect(0,0,200,200);//绘制一个矩形
    13. painter.drawLine(200,0,0,200);//绘制一个线段
    14. //改变视口
    15. //缩小
    16. painter.setViewport(0,0,200,200);
    17. painter.drawRect(0,0,100,100);//绘制一个矩形
    18. painter.drawLine(100,0,0,100);//绘制一个线段
    19. painter.setViewport(50,50,200,200);
    20. painter.drawRect(0,0,100,100);//绘制一个矩形
    21. painter.drawLine(100,0,0,100);//绘制一个线段
    22. }

     只修改窗口

    只修改窗口时,也是对窗口进行放大和缩小

    • setWindow() 的宽度和高度小于初始窗口的宽度和深度,相当于放大
    • setWindow() 的宽度和高度小于初始窗口的宽度和深度,相当于缩小
    • 宽倍数的计算:  初始窗口宽度/现窗口宽度
    • 高倍数的计算:  初始窗口高度/现窗口高度

    当setWindow()的初始坐标不为(0,0)时位置的计算:

    设setWindow(X,Y,M,N)         点位为Point(A,B)

    • 宽:  (A-X)*倍数
    • 高:(B-Y)*倍数

    当 setWindow()起始坐标未改变时:

    1. Widget::Widget(QWidget *parent)
    2. : QWidget(parent)
    3. , ui(new Ui::Widget)
    4. {
    5. ui->setupUi(this);
    6. resize(400,400);
    7. }
    8. void Widget::paintEvent(QPaintEvent *event)
    9. {
    10. QPainter painter(this);
    11. painter.setPen(Qt::cyan);
    12. painter.drawRect(0,0,200,200);//绘制一个矩形
    13. painter.drawLine(200,0,0,200);//绘制一个线段
    14. //改变窗口
    15. //缩小
    16. painter.setWindow(0,0,800,800);
    17. painter.drawRect(0,0,200,200);//绘制一个矩形
    18. painter.drawLine(200,0,0,200);//绘制一个线段
    19. //放大
    20. painter.setWindow(0,0,200,200);
    21. painter.drawRect(0,0,150,150);//绘制一个矩形
    22. painter.drawLine(150,0,0,150);//绘制一个线段
    23. }

     setWindow()的初始坐标不为(0,0)时

    1. Widget::Widget(QWidget *parent)
    2. : QWidget(parent)
    3. , ui(new Ui::Widget)
    4. {
    5. ui->setupUi(this);
    6. resize(400,400);
    7. }
    8. void Widget::paintEvent(QPaintEvent *event)
    9. {
    10. QPainter painter(this);
    11. painter.setPen(Qt::cyan);
    12. painter.drawRect(0,0,200,200);//绘制一个矩形
    13. painter.drawLine(200,0,0,200);//绘制一个线段
    14. //改变窗口
    15. painter.setWindow(50,50,100,100);
    16. QPen pen(Qt::red);
    17. pen.setWidth(2);
    18. painter.setPen(pen);
    19. painter.drawPoint(50,50);//绘制一个点
    20. painter.drawPoint(75,75);//绘制一个点
    21. painter.drawPoint(100,100);//绘制一个点
    22. }

     

    矩形的位置确定:

    1. Widget::Widget(QWidget *parent)
    2. : QWidget(parent)
    3. , ui(new Ui::Widget)
    4. {
    5. ui->setupUi(this);
    6. resize(400,400);
    7. }
    8. void Widget::paintEvent(QPaintEvent *event)
    9. {
    10. QPainter painter(this);
    11. painter.setPen(Qt::cyan);
    12. painter.drawRect(0,0,200,200);//绘制一个矩形
    13. painter.drawLine(200,0,0,200);//绘制一个线段
    14. //改变窗口
    15. painter.setWindow(50,50,100,100);
    16. QPen pen(Qt::red);
    17. pen.setWidth(2);
    18. painter.setPen(pen);
    19. painter.drawRect(0,0,100,100);
    20. painter.drawRect(50,50,100,100);
    21. }

     

     窗口和视口的综合使用:

    1.当窗口和视口相同时:根据窗口和视口的特性,显示窗口相当于没有改变。

    1. void Widget::paintEvent(QPaintEvent *event)
    2. {
    3. QPainter painter(this);
    4. painter.setPen(Qt::cyan);
    5. painter.drawRect(0,0,200,200);//绘制一个矩形
    6. painter.drawLine(200,0,0,200);//绘制一个线段
    7. //改变窗口和视口
    8. //窗口和视口相同
    9. painter.setWindow(0,0,100,100);
    10. painter.setViewport(0,0,100,100);
    11. //painter.setWindow(50,50,100,100);
    12. //painter.setViewport(50,50,100,100);
    13. painter.setPen(Qt::red);
    14. painter.drawRect(0,0,100,100);//绘制一个矩形
    15. painter.drawLine(100,0,0,100);//绘制一个线段
    16. }

     2.当窗口和视口不同时

    坐标相同,宽高不同时

    • 宽的倍数:视口宽/窗口宽
    • 高的倍数:视口高/窗口高
    1. void Widget::paintEvent(QPaintEvent *event)
    2. {
    3. QPainter painter(this);
    4. painter.setPen(Qt::cyan);
    5. painter.drawRect(0,0,200,200);//绘制一个矩形
    6. painter.drawLine(200,0,0,200);//绘制一个线段
    7. //改变窗口
    8. //窗口和视口不同
    9. painter.setWindow(0,0,100,100);
    10. painter.setViewport(0,0,50,50);
    11. painter.setPen(Qt::red);
    12. painter.drawRect(0,0,200,200);//绘制一个矩形
    13. painter.drawLine(200,0,0,200);//绘制一个线段
    14. }

    坐标不同,宽高相同(坐标为正数的话)

    • 修改窗口坐标,相当于往左上平移
    • 修改视口坐标,相当于往右下平移
    • 计算公式: X=窗口x-视口x   Y=窗口y-视口y
      • X大于0时往左平移,X小于0时往右平移
      • Y大于0时往上平移,Y小于0时往下平移
    1. void Widget::paintEvent(QPaintEvent *event)
    2. {
    3. QPainter painter(this);
    4. painter.setPen(Qt::cyan);
    5. painter.drawRect(0,0,200,200);//绘制一个矩形
    6. painter.drawLine(200,0,0,200);//绘制一个线段
    7. //改变窗口
    8. //窗口和视口不同
    9. //改变视口坐标,相当于平移
    10. painter.setWindow(0,0,100,100);
    11. painter.setViewport(50,50,100,100);
    12. painter.setPen(Qt::red);
    13. painter.drawRect(0,0,200,200);//绘制一个矩形
    14. painter.drawLine(200,0,0,200);//绘制一个线段
    15. }

    1. void Widget::paintEvent(QPaintEvent *event)
    2. {
    3. QPainter painter(this);
    4. painter.setPen(Qt::cyan);
    5. painter.drawRect(0,0,200,200);//绘制一个矩形
    6. painter.drawLine(200,0,0,200);//绘制一个线段
    7. //改变窗口
    8. //窗口和视口不同
    9. //修改窗口位置
    10. painter.setWindow(50,50,100,100);
    11. painter.setViewport(0,0,100,100);
    12. painter.setPen(Qt::red);
    13. painter.drawRect(0,0,200,200);//绘制一个矩形
    14. painter.drawLine(200,0,0,200);//绘制一个线段
    15. }

    当窗口不是正方形时,修改窗口时,可能图形会发生变化

    本该绘制一个正方型,但实际上绘制出来的时长方形

    1. Widget::Widget(QWidget *parent)
    2. : QWidget(parent)
    3. , ui(new Ui::Widget)
    4. {
    5. ui->setupUi(this);
    6. resize(400,300);//窗口大小为(400300
    7. }
    8. void Widget::paintEvent(QPaintEvent *event)
    9. {
    10. QPainter painter(this);
    11. painter.setWindow(-50,-50,100,100);
    12. painter.drawRect(0,0,25,25);//绘制一个正方形
    13. }

    通过改变视口来还原图形

        int side = qMin(width(), height());//获取两个参数的最小值

        int x=(width() - side)/2;  //调整宽度

        int y=(height() - side) /2;//调整高度
        painter.setViewport(x, y, side, side);//设置视口

    1. void Widget::paintEvent(QPaintEvent *event)
    2. {
    3. QPainter painter(this);
    4. painter.setWindow(-50,-50,100,100);
    5. int side = qMin(width(), height());
    6. painter.setViewport((width() - side)/2, (height() - side) /2, side, side);
    7. painter.drawRect(0,0,25,25);
    8. }

     

  • 相关阅读:
    MyBatisPlus带你快速入门(1)
    【C++学习手札】模拟实现vector
    Shell编程从看懂到看开②(字符串、数组、注释、流程控制、read读取控制台输入)
    C语言源代码系列-管理系统之机房机位预定系统
    flowable-ui部署
    ThingsBoard处理设备上报的属性并转换为可读属性
    “梦幻海陆空”三军联合军事演习国防教育活动方案
    java计算机毕业设计农产品交易系统源码+系统+mysql数据库+lw文档+部署
    【机器学习】python实现随机森林
    muduo第二章死锁问题
  • 原文地址:https://blog.csdn.net/qq_45303986/article/details/127972319