您的位置:首页 > 编程语言 > Qt开发

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)

在其重绘事件中

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()
获取指针的位置,这个位置是指针在桌面上的位置,鼠标的全局坐标也就是显示器上的坐标
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: