论Qt4的视口(ViewPort)与窗口(Window)

最近在研究Qt的2D绘图部分,对窗口和视口比较感兴趣,故写几个测试程序来加深理解。

PaintDemo.h

#ifndef PAINTDEMO_H
#define PAINTDEMO_H
#include <QWidget>
class QPaintEvent;

class PaintDemo : public QWidget
{
    public:
        PaintDemo();
    protected:
        void paintEvent(QPaintEvent *event);
};
#endif

PaintDemo.cpp

#include <QPainter>
#include "PaintDemo.h"

PaintDemo::PaintDemo()
{
    resize(800, 600);
    setWindowTitle(tr("Paint Demo"));
}

void PaintDemo::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setPen(QPen(Qt::black, 2));
    painter.drawLine(0,0,800,600);
}

在构造函数中将窗口大小设置为800x600,在paintEvent中从(0,0)到(800,600)绘制了一条Line,斜贯整个窗口:

此时,我们拉动改变窗口的大小,显然,窗口右下角的坐标不再是(800,600),而且其它更大的一个数值,譬如(900,700),而我们的线只画到(800,600),所以剩下的一段是空白。如下图所示:

OK,我们来修改一下代码,在绘制Line前加上一行

painter.setWindow(0,0,800,600);

修改后的PaintDemo.cpp代码如下(红色为增加的代码):

#include <QPainter>
#include "PaintDemo.h"

PaintedDemo::PaintedDemo()
{
    resize(800, 600);
    setWindowTitle(tr("Paint Demo"));
}

void PaintDemo::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setWindow(0,0,800,600);
    painter.setPen(QPen(Qt::black, 2));
    painter.drawLine(0,0,800,600);
}

编译运行:

这个时候我们发现不管怎样拉动窗口,Line永远贯穿整个窗口:

这说明painter.setWindow(0,0,800,600)将整个窗口设置为一个区域,左上角为原点,X坐标的终点为800,即窗口的宽度,Y坐标的终点为600,即窗口高度,这样,不管窗口怎么变化,右下角的坐标始终为(800,600),因此我们的Line始终贯穿整个窗口。

OK,我们再接再厉,将ViewPort也设置一下,PaintDemo.cpp代码如下(红色为增加的代码):

#include <QPainter>
#include "PaintDemo.h"

PaintDemo::PaintDemo()
{
    resize(800, 600);
    setWindowTitle(tr("Paint Demo"));
}

void PaintDemo::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setViewport(0,0,800,600);
    painter.setWindow(0,0,800,600);
    painter.setPen(QPen(Qt::black, 2));
    painter.drawLine(0,0,800,600);
}

 编译运行,这时我们会惊奇的发现,Line又不能贯穿整个窗口了

再来,我们将Viewport改小一点,宽度由800改为300,高度由600改为400,结果如何?看图:

现在可以得到结论了,Qt通过QPainter::setWindow将窗口坐标映射到视口坐标,而QPainter::setViewport则用来指定在窗体上所能绘制的区域。

关于Qt的坐标系统其实在Qt的doc里已经讲得很详细了,具体请参看:

http://qt-project.org/doc/qt-4.8/coordsys.html#window-viewport-conversion

这里借用一张图说明一下:

世界坐标通过矩阵转换成窗口坐标,然后通过窗口到视口的映射转换成设备坐标。

我这里的说明省略了矩阵变换,其实从逻辑坐标到窗口坐标之间还要进行矩阵变换。

转载于:https://www.cnblogs.com/realid/archive/2013/05/05/3061312.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值