当前位置:   article > 正文

视口和窗口的转换_窗口与视口的变换关系是怎样的?

窗口与视口的变换关系是怎样的?

一、基础概念:

QPainter的默认坐标系中,点(0,0)位于绘图设备的左上角,x坐标向右增长,y坐标向下增长。默认坐标系的每个像素占1 x 1大小的区域。

理论上,像素的中心取决于半像素坐标。例如,窗口部件的左上角像素覆盖了点(0,0)到点(1,1)的区域,它的中心在(0.5,0.5)位置。

视口和窗口密不可分。视口是物理坐标系下指定的任意矩形。窗口和视口是同一个矩形,但是窗口是逻辑坐标系,窗口可以定义视口的逻辑坐标范围

默认情况下,视口和窗口都设置设备的矩形。例如,如果设备是300 x 300的矩形,视口和窗口都是左上角为(0,0)的300 x 300 的相同矩形,此时逻辑坐标系和物理坐标系一致。

例如在逻辑坐标系下绘制一个左上角为(0,0)的100 x 100 的矩形,如下所示:

  1. Widget::Widget(QWidget *parent)
  2. : QWidget(parent)
  3. , ui(new Ui::Widget)
  4. {
  5. ui->setupUi(this);
  6. setPalette(QPalette(Qt::white));
  7. setAutoFillBackground(true);
  8. this->resize(300 , 300 ); // 设备坐标(物理坐标)
  9. }
  1. void Widget::paintEvent(QPaintEvent *event)
  2. {
  3. Q_UNUSED(event);
  4. QPainter painter(this);
  5. //设置画笔
  6. QPen pen;
  7. pen.setWidthF(1); //线宽
  8. pen.setStyle(Qt::SolidLine);//线的类型,实线、虚线等
  9. pen.setCapStyle(Qt::FlatCap);//线端点样式
  10. pen.setJoinStyle(Qt::BevelJoin);//线的连接点样式
  11. pen.setColor(Qt::gray); //划线颜色
  12. pen.setColor(Qt::red); //划线颜色
  13. painter.setPen(pen);
  14. painter.drawText(QPoint(width() / 2, 10), QString("widget size (%1, %2)")
  15. .arg(width()).arg(height()));
  16. pen.setColor(Qt::blue); //划线颜色
  17. painter.setPen(pen);
  18. painter.drawRect(0, 0, 100, 100);
  19. }

 

 由上图可知,逻辑坐标系和物理坐标系一致的。

二、视口与窗口:

QPainter提供了视口(Viewport)和窗口(Window)两个坐标系,通过QPainter内部的坐标变换矩阵自动转换为绘图设备的物理坐标。

视口表示绘图设备(例如QImage, QPicture, QPixmap, QWidget等)的任意一个矩形区域的物理坐标,可以只选取物理坐标的一个矩形区域用于绘图。默认情况下,视口(Viewport)等于绘图设备的整个矩形区,属于物理坐标系

视口矩形区域通过painter.setViewport(rect)方法设置,然后通过通过painter.setWindow()方法设定这个矩形区域的范围,配合使用,否则会出现问题(下文会举例写到)。

举例:在窗体部件(绘图设备)里取一块矩形(具体见代码)作为视口,同时设置视口矩形区域的范围(-100, -100, 200, 200),即左上角为(-100,-100),右下角为(100,100)。通过QPainter绘制一个左上角为(0,0),边长为100的正方形,如下所示:

  1. void Widget::paintEvent(QPaintEvent *event)
  2. {
  3. Q_UNUSED(event);
  4. QPainter painter(this);
  5. //设置画笔
  6. QPen pen;
  7. pen.setWidthF(1); //线宽
  8. pen.setStyle(Qt::SolidLine);//线的类型,实线、虚线等
  9. pen.setCapStyle(Qt::FlatCap);//线端点样式
  10. pen.setJoinStyle(Qt::BevelJoin);//线的连接点样式
  11. pen.setColor(Qt::gray); //划线颜色
  12. painter.setRenderHint(QPainter::Antialiasing);
  13. pen.setColor(Qt::red); //划线颜色
  14. painter.setPen(pen);
  15. int W = width();
  16. int H = height();
  17. painter.drawText(QPoint(width() / 2 - 10, 10), QString("widget size (%1, %2)")
  18. .arg(W).arg(H));
  19. int side = qMin(W, H);//去长和宽的小值
  20. // viewport矩形区
  21. QRect rect((W - side) / 2 + 100, (H - side) / 2 + 100, side - 200, side - 200);
  22. // 在原有坐标系下,绘制出Viewport区域
  23. painter.drawRect(rect);
  24. painter.drawText(QPoint(width()/2 - 50, 50), QString("rect size (%1, %2)")
  25. .arg(rect.width()).arg(rect.height()));
  26. painter.setViewport(rect);//设置 Viewport
  27. painter.setWindow(-100, -100, 200, 200); // 设置窗口范围,逻辑坐标
  28. // 绘制矩形中心十字线
  29. pen.setColor(Qt::gray);
  30. pen.setStyle(Qt::DashLine);
  31. painter.setPen(pen);
  32. painter.drawLine(QPoint(-100, 0), QPoint(100, 0));
  33. painter.drawLine(QPoint(0, -100), QPoint(0, 100));
  34. pen.setColor(Qt::blue); //划线颜色
  35. pen.setStyle(Qt::SolidLine);//线的类型,实线、虚线等
  36. painter.setPen(pen);
  37. painter.drawRect(0, 0, 100, 100);
  38. }

在上述代码中,如果未设置painter.setWindow()方法,即没有设定视口矩形的范围,系统将默认把绘图设备的区域,与视口矩形进行绑定。如果绘图设备是矩形的话,绘制的蓝色矩形将是个矩形,如果把绘图设备区域拉宽的话,蓝色矩形将被收窄。坐标原点都是左上角

如果将painter.setWindow(-100, -100, 200, 200)的范围,改成(-200, -200, 400, 400),蓝色的矩形将缩小一倍。

、逻辑坐标向物理坐标的转换:

由上面的例子,可以总结出转换规律:

默认情况视口和窗口坐标一致;如果设置视口矩形,窗口也要保证矩形一致,但需要通过setWindow方法设置矩形的逻辑坐标范围。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/589625
推荐阅读
相关标签
  

闽ICP备14008679号