Qt中坐标:窗口坐标,视口坐标
2015-12-21 22:39
561 查看
Qt中QPainter绘图在绘图设备上绘图的时候,会牵涉到坐标以及坐标相关的一些概念。
对于一个给定的绘图设备(paint device,qwidget,qpixmap等),在绘图时有两个坐标系:物理坐标系,逻辑坐标系。
物理坐标系是一个真实的坐标系,在Qt中,其原点处于绘图设备的左上角,其单位长度为绘图设备上一像素长度,其X轴向右增长,Y轴向下增长。
而逻辑坐标系是一个抽象的坐标系,其原点、单位长度没有实际意义,其X轴向右增长,Y轴向下增长。
绘图时,图像绘制在逻辑坐标系上,再通过窗口——视口映射,世界转换将逻辑坐标系映射到物理坐标系上。进而把绘制在逻辑坐标系上的图像映射到物理坐标系上。
窗口基于逻辑坐标系,视口基于物理坐标系。在没有做过改动的情况下,他们是一样的,都是以绘图设备大小为大小,左上角为原点(0,0)。使用以下两个函数可以修改一个基于逻辑坐标系的窗口矩形,与一个基于物理坐标系的视口矩形。
void QPainter::setWindow ( int x, int y, int width, int height )
void QPainter::setViewport ( int x, int y, int width, int height )
参数:
x:窗口/视口左上角x坐标 y:窗口/视口左上角y坐标
width:窗口/视口长度 height:窗口/视口高度
新建一个Qt5的窗口应用程序,基类选择QWidget,勾选ui。窗口的大小为400*300 也是Qt快速入门之中例子(10-3)
在其重绘事件中
在鼠标移动事件中
并且在构造函数中
程序执行后会在左上方显示一个绿色矩形,起始位置(0,0),大小(20,20),这个时候窗口和视口是一样的。
如果设置窗口
程序执行后会在左上方显示一个绿色矩形,起始位置(0,0),大小(80,60)。
为什么会这样?
窗口的起始位置并没有改变,但是大小设置为了100*100,实际的窗口(widget部件)大小是400*300 这样子就导致了像素点由以
前的1*1变为了4*3,所以,矩形的绘制20*20 就变为了20*4=80,20*3=60。
这个时候,我们本来想绘制的是正方形,结果是矩形,为了消除这种变形,需要采取窗口与视口对齐。
添加后,编译输出会发现是绿色的正方形,位置为(200,150),大小为(60,60)
经过setViewport的设置后,坐标原点由(0,0)变为了(x,y),此时的x=200,y=150,像素变为了300(视口设置)/100(窗口设置)=3,所以方形大小(60*60)
上面的例子中,涉及到了鼠标的移动事件中的坐标。
QMouseEvent中两类坐标系统,一类是窗口坐标,一类是显示器坐标。
QPoint QMouseEvent::pos() 获取指针在窗口中的位置。相对于主窗口的位置,也就是窗口坐标
QPoint QMouseEvent::globalPos()
获取指针的位置,这个位置是指针在桌面上的位置,鼠标的全局坐标也就是显示器上的坐标
对于一个给定的绘图设备(paint device,qwidget,qpixmap等),在绘图时有两个坐标系:物理坐标系,逻辑坐标系。
物理坐标系是一个真实的坐标系,在Qt中,其原点处于绘图设备的左上角,其单位长度为绘图设备上一像素长度,其X轴向右增长,Y轴向下增长。
而逻辑坐标系是一个抽象的坐标系,其原点、单位长度没有实际意义,其X轴向右增长,Y轴向下增长。
绘图时,图像绘制在逻辑坐标系上,再通过窗口——视口映射,世界转换将逻辑坐标系映射到物理坐标系上。进而把绘制在逻辑坐标系上的图像映射到物理坐标系上。
窗口基于逻辑坐标系,视口基于物理坐标系。在没有做过改动的情况下,他们是一样的,都是以绘图设备大小为大小,左上角为原点(0,0)。使用以下两个函数可以修改一个基于逻辑坐标系的窗口矩形,与一个基于物理坐标系的视口矩形。
void QPainter::setWindow ( int x, int y, int width, int height )
void QPainter::setViewport ( int x, int y, int width, int height )
参数:
x:窗口/视口左上角x坐标 y:窗口/视口左上角y坐标
width:窗口/视口长度 height:窗口/视口高度
新建一个Qt5的窗口应用程序,基类选择QWidget,勾选ui。窗口的大小为400*300 也是Qt快速入门之中例子(10-3)
在其重绘事件中
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setBrush(Qt::green);
painter.drawRect(0, 0, 20, 20); //矩形绘制
}
在鼠标移动事件中
void Widget::mouseMoveEvent(QMouseEvent *event)
{
QString pos = QString("%1,%2").arg(event->pos().x()).arg(event->pos().y());
QToolTip::showText(event->globalPos(), pos, this);
}
并且在构造函数中
setMouseTracking(true); //不用点击 也能触发
程序执行后会在左上方显示一个绿色矩形,起始位置(0,0),大小(20,20),这个时候窗口和视口是一样的。
如果设置窗口
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setWindow(0, 0, 100, 100);
painter.setBrush(Qt::green);
painter.drawRect(0, 0, 20, 20);
}
程序执行后会在左上方显示一个绿色矩形,起始位置(0,0),大小(80,60)。
为什么会这样?
窗口的起始位置并没有改变,但是大小设置为了100*100,实际的窗口(widget部件)大小是400*300 这样子就导致了像素点由以
前的1*1变为了4*3,所以,矩形的绘制20*20 就变为了20*4=80,20*3=60。
这个时候,我们本来想绘制的是正方形,结果是矩形,为了消除这种变形,需要采取窗口与视口对齐。
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
//是让视口和窗口同高防止变形
int side = qMin(width(), height()); //取小值 300
int x = (width() / 2); //200
int y = (height() / 2); //150
//设置视口
painter.setViewport(x, y, side, side); //移动了实际坐标 新的坐标(200,150,300,300)
painter.setWindow(0, 0, 100, 100);//逻辑宽 高 100 实际的会被100等分
painter.setBrush(Qt::green);
painter.drawRect(0, 0, 20, 20);
}
添加后,编译输出会发现是绿色的正方形,位置为(200,150),大小为(60,60)
经过setViewport的设置后,坐标原点由(0,0)变为了(x,y),此时的x=200,y=150,像素变为了300(视口设置)/100(窗口设置)=3,所以方形大小(60*60)
上面的例子中,涉及到了鼠标的移动事件中的坐标。
QMouseEvent中两类坐标系统,一类是窗口坐标,一类是显示器坐标。
QPoint QMouseEvent::pos() 获取指针在窗口中的位置。相对于主窗口的位置,也就是窗口坐标
QPoint QMouseEvent::globalPos()
获取指针的位置,这个位置是指针在桌面上的位置,鼠标的全局坐标也就是显示器上的坐标
相关文章推荐
- 自学QT之常量中有换行符错误的解决办法
- QT实现应用程序重启
- Qt多线程编程
- Qt的4个图像类QImage/QPixmap/QBitmap/QPicture
- QT如何在点关闭按钮时执行一些操作
- QT完美转换特殊字符的大小写
- py2.7+pyqt4+Eric4 完美桌面开发配置
- 收集了一个pyqt4做的浏览器
- Qt中QSettings的用法(记住密码和自动登录)
- QT5中使用Echarts图表组件
- QT的阻塞与非阻塞延时
- VS2015和QT5.5项目出现的诡异错误(LNK2001和LNK09)的解决办法
- Qt自动补全(QCompleter或QListView)
- Qt学习——QListWidget控件的使用
- qt下信号发送机制
- qt超强精美绘图控件 - QCustomPlot一览 及 安装使用教程
- qt的关闭窗口
- Qt之界面实现技巧
- pyqt桌面开发--HelloWorld
- PyQt5教程(八)——拖放