Qt进修之路(28):坐标调动
副标题#e#
颠末前面的章节,我们已经可以或许画出一些对象来,主要就是利用QPainter的相关函数。本日,我们要看的是QPainter的坐标系统。
同许多坐标系统一样,QPainter的默认坐标的原点(0, 0)位于屏幕的左上角,X轴正偏向是程度向右,Y轴正偏向是竖直向下。在这个坐标系统中,每个像素占据1 x 1的空间。你可以把它想象成是一张坐标值,个中的每个小格都是1个像素。这么说来,一个像素的中心实际上是一个“半像素坐标系”,也就是说,像素(x, y)的中心位置其实是在(x + 0.5, y + 0.5)的位置上。因此,假如我们利用QPainter在(100, 100)处绘制一个像素,那么,这个像素的中心坐标是(100.5, 100.5)。
这种细微的不同在实际应用中,出格是对坐标要求准确的系统中是很重要的。首先,只有在克制反走样,也就是默认状态下,才会有这0.5像素的偏移;假如利用了反走样,那么,我们画(100, 100)位置的像素时,QPainter会在(99.5, 99.5),(99.5, 100.5),(100.5, 99.5)和(100.5, 100.5)四个位置绘制一个亮色的像素,这么发生的结果就是在这四个像素的核心处(100, 100)发生了一个像素。假如不需要这个特性,就需要将QPainter的坐标系平移(0.5, 0.5)。
这一特性在绘制直线、矩形等图形的时候城市用到。下图给出了在没有反走样技能时,利用drawRect(2, 2, 6, 5)绘制一个矩形的示例。在No Pen的环境下,请留意矩形左上角的像素是在(2, 2),个中心位置是在(2.5, 2.5)的位置。然后留意下有差异的Pen的值的绘制样式,在Pen宽为1时,实际画出的矩形的面积是7 x 6的(图出自C++ GUI Programming with Qt4, 2nd Edition):
在具有反走样时,利用drawRect(2, 2, 6, 5)的结果如下(图出自C++ GUI Programming with Qt4, 2nd Edition):
留意我们前面说过,通过平移QPainter的坐标系来消除着0.5像素的差别。下面给出了利用drawRect(2.5, 2.5, 6, 5)在反走样环境下绘制的矩形(图出自C++ GUI Programming with Qt4, 2nd Edition):
请比拟与上图的区别。
在上述的QPainter的默认坐标系下,QPainter提供了视口(viewport)窗口(window)机制,用于绘制与绘制设备的巨细和判别率无关的图形。视口和窗口是细密的接洽在一起的,它们一般都是矩形。视口是由物理坐标确定其巨细,而窗口则是由逻辑坐标抉择。我们在利用 QPainter举办绘制时,传给QPainter的是逻辑坐标,然后,Qt的画图机制会利用坐标调动将逻辑坐标转换成物理坐标后举办绘制。
凡是,视口和窗口的坐标是一致的。好比一个600 x 800的widget(这是一个widget,或者是一个对话框,或者是一个面板等等),默认环境下,视口和窗口都是一个320 x 200的矩形,原点都在(0, 0),此时,视口和窗口的坐标是沟通的。
留意到QPainter提供了setWindow()和setViewport()函数,用来配置视口和窗口的矩形巨细。好比,在上面所述的 320 x 200的widget中,我们要配置一个从(-50, -50)到(+50, +50),原点在中心的矩形窗口,就可以利用
painter.setWindow(-50, -50, 100, 100);
个中,(-50, -50)指明白原点,100, 100指明白窗口的长和宽。这里的“指明原点”意思是,逻辑坐标的(-50, -50)对应着物理坐标的(0, 0);“长和宽”说明,逻辑坐标系下的长100,宽100实际上对应物理坐标系的长320,宽200。
或者你已经发明这么一个长处,我们可以随时改变window的范畴,而不改变底层物理坐标系。这就是前面所说的,视口与窗口的浸染:“绘制与绘制设备的巨细和判别率无关的图形”,如下图所示(图出自C++ GUI Programming with Qt4, 2nd Edition):
#p#副标题#e#
除了视口与窗口的变革,QPainter还提供了一个“世界坐标系”,同样也可以调动图形。所差异的是,视口与窗话柄际上是统一图形在两个坐标系下的表达,而世界坐标系的调动是通过改变坐标系来平移、缩放、旋转、剪切图形。为了清楚起见,我们来看下面一个例子:
void PaintedWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QFont font("Courier", 24);
painter.setFont(font);
painter.drawText(50, 50, "Hello, world!");
QTransform transform;
transform.rotate(+45.0);
painter.setWorldTransform(transform);
painter.drawText(60, 60, "Hello, world!");
}
#p#分页标题#e#
为了显示利便,我在这里利用了QFont改变了字体。QPainter的drawText()函数提供了绘制文本的成果。它有几种重载形式,我们利用了个中的一种,即拟定文本的坐标然后绘制。需要留意的是,这里的坐标是文字
左下角
的坐标(出格提醒这一点,因为许多画图系统,好比Java2D都是把左上角作为坐标点的)!下面是运行功效:
我们利用QTransform做了一个rotate调动。这个调动就是旋转,并且是顺时针旋转45度。然后我们利用这个调动配置了 QPainter的世界坐标系,留意到QPainter是一个状态机,所以这种调动并不会改变之前的状态,因此只有第二个Hello, world!被旋转了。确切的说,
被旋转的是坐标系而不是这个文字!请留意体会这两种说法的差异。
出处:http://devbean.blog.51cto.com/448512/239585