QT二维绘图
8-1 用QPainter绘图(Painting with QPainter)
要在绘图设备(paint device,一般是一个控件)上开始绘制,我们只要创建一个QPainter,把绘图设备指针传给QPainter对象。例如:
oid MyWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    ...
}
使用QPainter的draw…()函数我们可以绘制各种图形。图8.1给出了主要的一些。绘制的方式由QPainter的设置决定。设置的一部分是从绘图设备得到的,其他是初始化时的默认值。三
个主要的设置为:画笔,刷子和字体。
画笔用来绘制直线和图形的边框。包含颜,宽度,线型,角设置和连接设置。
刷子是填充几何图形的方式。包含颜,方式设置,也可以是一个位图或者渐变。
字体用来绘制文本。字体的属性很多,如字体名,字号等。
 
这些设置随时可以改变,可用QPen,QBrush,QFont对象调用setPen(),setBrush(),setFont()修改。 
Figure 8.1. QPainter's most frequently () functions
Figure 8.2. Cap and join styles
Figure 8.3. Pen styles
Figure 8.4. Predefined brush styles
现在来看看具体的例子。下面的代码是绘制图8.5(a)中椭圆的代码:
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(Qt::black, 12, Qt::DashDotLine, Qt::RoundCap));
painter.setBrush(QBrush(Qt::green, Qt::SolidPattern));
painter.drawEllipse(80, 80, 400, 240);
调用函数setRenderHint(QPainter::Antialiasing,true),使绘制时边缘平滑,使用颜浓度的变化,把图形的边缘转换为象素时引起的扭曲变形尽可能减少,在支持这一功能的平台或者绘图设备上得到一个平滑的边缘。
Figure 8.5. Geometric shape examples
 
下面的代码是图8.5(b)中绘制扇形的代码:
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(Qt::black, 15, Qt::SolidLine, Qt::RoundCap,
                    Qt::MiterJoin));
painter.setBrush(QBrush(Qt::blue, Qt::DiagCrossPattern));
painter.drawPie(80, 80, 400, 240, 60 * 16, 270 * 16);
函数drawPie()的最后两个参数值的单位为一度的十六分之一。
下面的代码是图8.5(c)中绘制贝赛尔曲线的代码:
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
QPainterPath path;
veTo(80, 320);
qt viewport
path.cubicTo(200, 80, 320, 80, 480, 320);
painter.setPen(QPen(Qt::black, 8));
painter.drawPath(path);
通过连接基本图形元素,直线,椭圆,多段线,圆弧,二次和三次贝塞尔曲线等,QPainterPath类能确定任何矢量图形。因此,绘图路径(Painter paths)是最基本的绘制元素,任何图形和图形的组合都可以同路径(path)表示。
一个路径能够确定一个轮廓,由这个轮廓确定的区域可以由刷子来填充。在图8.5(c)中我们没有设置刷子,因此只绘制了轮廓。
以上的三个例子都是使用了默认的刷子(Qt::SolidePattern,Qt::DiagCrossPattern,Qt::NoBrush)。在现在的应用程序中,单填充已经很少使用,渐变填充开始收到欢迎。渐变是依靠颜的变化实现两种或者多种颜之间平滑的过渡。渐变通常用来处理3D效果,如使用Plastique渐变方式来表现QPushButtons。
Qt支持三种类型的渐变:线形渐变,圆锥渐变和圆形渐变(linear, conical, and radial)。下一节的OvenTimer例子就是在一个控件中使用了所有这三种渐变。
线形渐变由两个控制点和直线上的一系列颜点组成。图8.6由下面的代码得到:在两个控制点之间,在三个不同的位置确定了三个不同的颜值。位置有0到1的浮点数得到,0为第一个控制点,1为第二个控制点。不同位置点之间的颜由差值计算得到。
LinearGradient gradient(50, 100, 300, 350);
gradient.setColorAt(0.0, Qt::white);
gradient.setColorAt(0.2, Qt::green);
gradient.setColorAt(1.0, Qt::black);
Figure 8.6. QPainter's gradient brushes
 
圆形渐变由颜组,圆心(xc,yc),半径r和焦点(xf,yf)定义。圆心和半径定义一个圆,颜从焦点开始扩散到周围,焦点可以是圆心也可以是圆内的任意一个点。
圆锥渐变由圆心(xc,yc)和一个角度a定义。颜从圆心开始像表的秒针一样扩散。
我们已经提到了QPainter的画笔,刷子和字体设置。此外,QPainter还有其他一些设置影响图形和文字的绘制:
1.      背景刷子,当背景模式为Qt::OpaqueMode(缺省值为Qt::transparentMode)时,背景刷子用来填充几何图形,文字,和位图的背景(在绘图刷子的下面)
2.      刷子的起点:刷子的起始绘制点,通常为控件的左上角。
3.      剪辑区域,剪辑区域为绘图设备上可以绘制的区域,在剪辑区域意外进行的绘制是无效的。
4.      视口,窗口,世界坐标:这三个决定了QPainter的逻辑坐标映射到物理坐标的方式。通常,逻辑坐标和物理坐标是重合的。坐标系统在下一节介绍。
5.      组合方式:组合方式决定绘制设备上新绘制的象素和已经存在的象素的影响方式。缺省方式为覆盖式(source over),新象素画在已有元素的上面。只是有限一个绘图设备支持组合方式的设置,将在本章后面介绍
在任何时候,我们可以调用save()把QPainter当前的设置保存在一个内部栈里,然后调用restore()进行恢复。我们能够临时改变QPainter的一些设置,然后恢复先前的值。
2 坐标变换(Painter Transformations)
在QPainter的初始坐标系统中,点(0,0)位于绘图设备的左上角。X轴坐标向右递增,y轴向下递增,一个象素占据1×1的面积。
需要说明的一点是一个象素的中心位于坐标的一半处。例如,左上角位于点(0,0)和点(1,1)之间区域的象素,它的中心位于(0.5,0.5)。如果我们使用QPainter绘制一个位置在(100,100)的象素,QPainter会在每个坐标值上增加0.5,以坐标(100.5,100.5)为中心绘制这个象素。
一个需要注意的事情是,一个象素的中心位于象素坐标的“半象素”坐标。例如,窗口左上角象素占据从点(0,0)到(1,1)的位置,它的中心位于(0.5,0.5)。如果我们需要QPainter在点(100,100)的坐标处绘制另一个象素,QPainter将会在两个坐标轴方向偏移0.5个坐标点,即象素的中心点将会位于(100.5,100.5)。
这个偏移看起来有些教条,但是实际上有这重要的作用。首先,在禁止消除锯齿功能(缺省设置)时才进行0.5的偏移。如果许可了消除锯齿功能,QPainter会在(100,100)的位置绘制一个黑的象素。事实是QPainter在(99.5,99.5),(99.5,100.5),(100.5,99.0),(100.5,100.5)绘制亮灰象素,这样产生的效果就是一个黑象素位于四个象素的焦点(100,100)处。如果我们不需要这个功能,可以把坐标偏移半个象素。
在绘制直线,矩形,椭圆时,上述规则都是适用的。图8.7表明了在不用消除锯齿功能时,用不同的笔宽度绘制矩形drawRect(2,2,6,5)的不同结果。需要特别注意用1象素的笔宽绘制6*5的矩形时实际的矩形面积为7*6。这和以前的Qt版本不同,但是这个功能对绘制看缩放的,独立于分辨率的矢量图形很有帮助。
Figure 8.7. Drawing a 6 x 5 rectangle with no antialiasing
现在我们已经理解了Qt的默认坐标系同,现在再来了解QPainter的视口(viewport),窗口(window)和世界坐标系矩阵(world matrix)的变化。(在这一节中,窗口(window)不是控件的窗口,视口(viewport)也和QScrollArea的视口也没有联系)
窗口和视口是紧密联系在一起的。视口是由物理坐标确定的任意矩形。窗口是由逻辑坐标表示的视口大小。QPainter在进行绘制时,我们给QPainter的是逻辑坐标,根据视口和窗口的设置,这些逻辑坐标通过线形变换,转换为物理坐标。
通常,窗口和视口的大小和绘图设备是一致的。例如,一个320*200的控件,视口和窗口都是一个320*200的矩形,起始点(0,0)位于左上角。这时,逻辑坐标和物理坐标是相同的。
视口窗口机制是为了绘制与绘图设备的大小和分辨率无关的图形。如果我们的逻辑坐标设置为从(-50,-50)到(+50,+50)的矩形,(0,0)点在中心。如下这样设置窗口:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。