目录
Paint System
Coordinate System
绘图系统(Paint System)
Qt的绘画系统可以使用相同的API在屏幕和打印设备上进行绘画,并且主要基于QPainter、QPaintDevice和QPaintEngine类。
QPainter用于执行绘图操作;QPaintDevice是二维空间的抽象,可以使用QPainter在其上绘制;QPaintEngine提供了QPainter用于在不同类型的设备上绘制的接口,QPaintEngine类在内部由QPainter和QPaintDevice使用。

这种方法的主要优点是,所有绘制都遵循相同的绘制管道,从而可以轻松添加对新功能的支持,并为不受支持的功能提供默认实现。
绘图坐标系统(Paint Coordinate System)
坐标系由QPainter类控制。QPainter与QPaintDevice和QPaintEngine类一起构成了Qt绘画系统的基础。QPaint用于执行绘图操作,QPaintDevice是二维空间的抽象,可以使用QPainter在其上绘制,而QPaintEngine提供了QPainter用于在不同类型的设备上绘制的接口。
QPaintDevice类是可以绘制的对象的基类:其绘制功能由QWidget、QImage、QPixmap、QPicture和QOpenGLPaintDevices类继承。绘制设备的默认坐标系的原点位于左上角。x值向右增加,y值向下增加。默认单位是基于像素的设备上的一个像素和打印机上的一点(1/72英寸)。
逻辑QPainter坐标到物理QPaintDevice坐标的映射由QPainter的变换矩阵(transformation)、视口(viewport)和“窗口(window)”处理。默认情况下,逻辑坐标系和物理坐标系重合。QPainter还支持坐标变换(例如旋转和缩放)。
渲染(Rendering)
逻辑表示(Logical Representation)
图形基本体的大小(宽度和高度)始终与其数学模型相对应,而忽略了渲染时使用的QPen的宽度:

走样绘制(Aliased Painting)
绘制时,像素渲染由QPainter::Antialiasing render hint控制。
RenderHint枚举用于指定QPainter的标志,这些标志可能会被任何给定引擎所遵循,也可能不会被任何给定的引擎所遵循。QPainter::Antialiasing值指示引擎应尽可能对基本体的边缘进行抗锯齿,即使用不同的颜色强度平滑边缘。
但默认情况下,painter是走样的(aliased),这时的规则是:当使用1像素宽的笔进行渲染时,像素将被渲染到数学定义的点的右下方。例如:(QPen:1像素宽)

当使用像素为偶数的笔进行渲染时,像素将围绕数学定义的点对称渲染;而使用像素为奇数的笔渲染时,多余的像素将渲染到数学点的右侧和下方,就像在一个像素的情况下一样。具体示例请参见下面的QRectF图。

请注意,由于历史原因,对于QRect(而非QRectF),QRect::right()和QRect::bottom()函数的返回值偏离了矩形的真实右下角。
QRect的right()函数返回left()+width()-1,bottom()函数则返回top()+height()-1。图中右下角的绿色点显示了这些函数的返回坐标。
我们建议你只使用QRectF:QRectF类使用浮点坐标在平面中定义一个矩形,以确保准确性(QRect使用整数坐标),QRectF::right()和QRectF::bottom()函数确实会返回 [真实的] 右下角。
或者,使用QRect,应用x()+width()和y()+height()来查找右下角,并避免使用right()和bottom()函数。
抗锯齿绘制(Anti-aliased Painting)
如果设置QPainter的抗锯齿(anti-aliasing)渲染提示(render hint),像素将在数学定义的点的两侧对称渲染:

变换(Transformations)
默认情况下,QPainter在关联设备自己的坐标系上操作,但它也完全支持仿射坐标变换。
可以使用QPainter::scale()函数按给定偏移量缩放坐标系,可以使用QPainter::rotate()函数顺时针旋转坐标系,也可以使用QPainter::translate()函数平移坐标系。

还可以使用QPainter::shear()函数围绕原点扭曲坐标系。所有转换操作都是在操作QPainter的转换矩阵(transformation matrix),你可以使用QPainter::worldTransform()函数获取该矩阵。矩阵将平面中的一个点转换为另一个点。
如果需要反复进行相同的变换,还可以使用QTransform对象以及QPainter::worldTransform()和QPainter::setWorldTransorm()函数。你可以随时通过调用QPainter::save()函数保存QPainter的转换矩阵,该函数将矩阵保存在内部堆栈上。QPainter::restore()函数将其弹出。
转换矩阵的一个常见需求是在各种绘制设备上重用相同的绘图代码。在没有变换的情况下,结果将与绘制设备的分辨率紧密相关。打印机具有高分辨率,例如每英寸600点,而屏幕通常每英寸72到100点。
Analog Clock Example

void AnalogClockWindow::render(QPainter *p) {
static const QPoint hourHand[3] = {
QPoint(7

本文深入探讨了Qt绘图系统的架构与实现细节,包括绘图API、坐标系统、渲染技术及坐标变换等内容。通过示例代码讲解了如何利用Qt进行高效、精确的图形绘制。
最低0.47元/天 解锁文章
752

被折叠的 条评论
为什么被折叠?



