QT 坐标系
坐标系由 QPainter 类控制。与QPaintDevice和QPaintEngine类一起,QPainter构成了Qt绘画系统Arthur的基础。QPainter用于执行绘图操作,QPaintDevice是二维空间的抽象,可以使用QPainter进行绘制,QPaintEngine提供了画家用来绘制到不同类型的设备上的界面。
QPaintDevice 类是可以绘制的对象的基类:其绘制功能由 QWidget、QImage、QPixmap、QPicture 和 QOpenGLPaintDevice 类继承。绘画设备的默认坐标系的原点位于左上角。x 值向右增加,y 值向下增加。在基于像素的设备上,默认单位为 1 个像素,在打印机上,默认单位为 1 个点(1/72 英寸)。
逻辑 QPainter 坐标到物理 QPaint设备的映射由 QPainter 的转换矩阵、视口和"窗口"处理。默认情况下,逻辑坐标系和物理坐标系重合。QPainter 还支持坐标变换(例如旋转和缩放)。
渲染
逻辑坐标系
图形基元的大小(宽度和高度)始终与其数学模型相对应,忽略其呈现笔的宽度:
锯齿绘画
绘制时,像素呈现由 QPainter::Antialiasing控制。
RenderHint 枚举用于为 QPainter 指定任何给定引擎可能遵守也可能不遵守的标志。QPainter::Antialiasing值指示引擎应尽可能对基元的边缘进行抗锯齿,即通过使用不同的颜色强度来平滑边缘。
但默认情况下,画家会带有锯齿,规则是:使用一个像素宽的笔进行渲染时,像素将呈现在数学上定义的点的右侧和下方。例如:
使用具有偶数个像素的笔进行渲染时,像素将围绕数学定义的点进行对称渲染,而使用具有奇数个像素的笔进行渲染时,备用像素将呈现在数学点的右侧和下方,如在一个像素的情况下。有关具体示例,请参阅下面的 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() 函数。
消除锯齿绘画
如果您设置了QPainter的抗锯齿渲染提示,则像素将在数学定义点的两侧按对称方式渲染:
坐标转换
默认情况下,QPainter 在关联设备自己的坐标系上运行,但它也完全支持仿射坐标变换。
您可以使用 QPainter::scale() 函数按给定的偏移量缩放坐标系,可以使用 QPainter::rotate() 函数顺时针旋转坐标系,还可以使用 QPainter::translate() 函数平移坐标系(即向点添加给定偏移量)。
您还可以使用 QPainter::shear() 函数围绕原点扭曲坐标系。所有转换操作都在 QPainter 的转换矩阵上运行,您可以使用 QPainter::worldTransform() 函数检索该矩阵。矩阵将平面中的一个点转换为另一个点。
如果你需要一遍又一遍地进行相同的转换,你也可以使用 QTransform 对象和 QPainter::worldTransform() 和 QPainter::setWorldTransform() 函数。您可以随时通过调用 QPainter::save() 函数来保存 QPainter 的转换矩阵,该函数将矩阵保存在内部堆栈上。QPainter::restore() 函数会将其弹出。
转换矩阵的一个常见需求是在各种绘画设备上重用相同的绘图代码。如果不进行变换,结果将与绘画设备的分辨率紧密绑定。打印机具有高分辨率,例如每英寸600点,而屏幕通常每英寸72至100点。
模拟时钟 例子 Analog Clock Example
模拟时钟示例显示了如何使用 QPainter 的转换矩阵绘制自定义小部件的内容。
建议您先编译并运行此示例,然后再继续阅读。特别是,尝试将窗口大小调整为不同的大小。
void AnalogClockWindow::render(QPainter *p