Qt4中的2D绘图系统称为Arthur绘图系统,可使用相同的API在屏幕上和绘图设备上进行绘制,主要基于QPainter、QPainterDevice和 QPainterEngine。QPainter执行绘图操做,QPainterDevice提供绘图设备,是一个二维空间的抽象,QPainterEngine提供一些接口。QPainter用来执行具体的绘图相关操做,如画点,画线,填充,变换,alpha通道等。QPaintDevice类是可以进行绘图的对象的基类,QWidget,QPixmap,QPicture,QImage,以及QPrinter类继承了QPaintEngine类的绘图能力,QPainter类能够在一切继承QPainterDevice的子类上进行绘制操做。算法
QT中Arthur绘图框架中的基本绘图元素是画笔,画刷。
QPainter类具备GUI程序须要的绝大多数函数,可以绘制基本图形(点,线,矩形,多边形等)以及复杂的图形(如绘图路径)。使用绘图路径(QPaintPath)的优势是复杂形状的图形只用生成一次,再使用的时候只需要调用QPainter::drawPath()就能够绘制。QPainterPath对象能够用来填充,绘制轮廓。
线和轮廓均可以用画笔(QPen)进行绘制,画刷(QBrush)进行填充。画笔定义风格(线形),宽度,笔尖画刷以及端点是如何绘制的(cap-style),端点的链接方式(join-style)。画刷用来填充画笔绘制的图形,能够定制不一样的填充模式和颜色的画刷。
当绘制文字时,字体使用QFont类定义,Qt使用指定字体的属性,若是没有匹配的字体,Qt将使用最接近的字体。字体属性能够经过QFontInfo来获取。字体的度量(measurement)使用QFontMetrics类来获取。QFontDatabase类能够得到底层窗口系统全部可用的字体。windows
一般状况下QPainter以默认的坐标系统进行绘制,也能够用QMatrix类对坐标进行变换。
当绘制时,可使用QPainter::SetRenderHint函数设置绘图引擎是否启用反锯齿功能使图变得平滑。并发
QPainter::Antialiasing尽可能进行边的反锯齿绘制
QPainter::TextAntialiasing 尽量进行文字的反锯齿绘制
QPainter::SmoothPixmapTransform 使用平滑的pixmap变换算法(双线性插值算法),而不是近邻插值算法mvc
重绘事件处理函数:框架
void QWidget::paintEvent ( QPaintEvent * event )ide
基础部件类Qwidget提供的paintEvent函数,是纯虚函数;Qwidget的子类要使用paintEvent函数必须从新实现。在三种状况会发生重绘事件调用paintEvent函数: svg
A、当窗口部件第一次显示时,系统会自动产生一个绘图事件函数
B、repaint()与update()函数被调用时工具
C、当窗口部件被其余部件遮挡,而后又再次显示出来时,就会对隐藏的区域产生一个重绘事件post
D、从新调整窗口大小时
绘图时须要先定义一个QPainter类对象,绘图工具可使Qpen(画笔)和QBrush(画刷)。Qpen(画笔)来绘制轮廓线,QBrush(画刷)用来填充,使用QPen写文本时还能够指定字体(QFont类)。
画笔的属性包括线型,线宽,颜色等。
A、QPen主要成员函数以下:
QPen(Qt::PenStyle style)
QPen(const QColor & color)
QPen(const QBrush & brush, qreal width, Qt::PenStyle style = Qt::SolidLine, Qt::PenCapStyle cap = Qt::SquareCap, Qt::PenJoinStyle join = Qt::BevelJoin)
QPen(const QPen & pen)
void setBrush(const QBrush & brush)
void setCapStyle (Qt::PenCapStyle style)
void setColor (const QColor & color)
void setJoinStyle (Qt::PenJoinStyle style)
void setWidth (int width)
画笔的属性能够在构造函数中指定,也可使用setStyle(),setWidth(),setBrush(),setCapStyle(),setJoinStyle()等函数设定画笔的各项属性。Qt中使用Qt::PenStyle定义了6种画笔风格,分别是Qt::SolidLine,Qt::DashLine,Qt::DotLine,Qt::DashDotLine,Qt::DashDotDotLine,Qt::CustomDashLine。自定义线风格(Qt::CustomDashLine),须要使用QPen的setDashPattern()函数来设定自定义风格。
画笔的设置代码以下:
QPainter painter(this);
QPen pen(Qt::green, 3, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin);
painter.setPen(pen);
等价于以下代码:
QPainter painter(this);
QPen pen; // creates a default pen
pen.setStyle(Qt::DashDotLine);
pen.setWidth(3);
pen.setBrush(Qt::green);
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin);
painter.setPen(pen);
B、画笔风格
画笔风格使用Qt::PenStyle枚举定义。
C、画笔的端点风格( Qt::PenCapStyle)
画笔端点风格决定了线的端点样式,只对线宽大于1的线有效。Qt使用枚举定义了三种端点风格,分别为Qt::SqureCap,QT::FlatCap,Qt::RoundCap。
D、画笔链接风格(Qt::PenJoinStyle)
画笔链接风格是两条线如何链接,链接风格对线宽大于等于1的线有效。Qt使用枚举定义了四种链接类型,分别是Qt::MiterJoin,Qt::BevelJoin,Qt::RoundJoin,Qt::SvgMiterJoin。
在Qt中图形使用QBrush进行填充,画刷包括填充颜色和填充模式(风格)。
A、QBrush主要成员函数
QBrush(Qt::BrushStyle style)
QBrush(const QColor& color,Qt::BrushStyle style = Qt::SolidPattern)
QBrush(Qt::GlobalColor color,Qt::BrushStyle style = Qt::SolidPattern)
QBrush(const QColor & color, const QPixmap & pixmap)
QBrush(Qt::GlobalColor color, const QPixmap & pixmap)
QBrush(const QPixmap & pixmap)
QBrush(const QImage & p_w_picpath)
QBrush(const QBrush & other)
QBrush(const QGradient & gradient)
const QColor &color() const
const QGradient *gradient() const
const QMatrix &matrix() const
void setColor(const QColor & color)
void setColor(Qt::GlobalColor color)
void setMatrix(const QMatrix & matrix)
void setStyle(Qt::BrushStyle style)
void setTexture(const QPixmap & pixmap)
void setTextureImage(const QImage & p_w_picpath)
void setTransform(const QTransform & matrix)
Qt::BrushStyle style() const
QPixmap texture() const
QImage textureImage() const
QTransform transform() const
B、填充颜色
在Qt中,颜色使用QColor类表示,QColor支持RGB,HSV,CMYK颜色模型。QColor还支持alpha混合的轮廓和填充。RGB是面向硬件的模型,颜色由红绿蓝三种基色混合而成;HSV模型比较符合人对颜色的感受,由色调(0-359),饱和度(0-255),亮度(0-255)组成;CMYK由青,洋红,黄,黑四种基色组成,主要用于打印机等硬件拷贝设备上,每一个颜色份量的取值是0-255。
C、填充模式
填充模式经过枚举类型Qt::BrushStyle来实现,默认值是Qt::NoBrush,不进行任何填充;填充模式包括基本填充模式,渐变填充,和纹理填充模式。不一样的填充模式显示效果以下:
Qt4中,QBrush提供了三种渐变填充:线性(QLinearGradient),圆形(QRadialGradient)和圆锥渐变(QConicalGradient),全部的类都从QGradient类继承。
线性渐变填充
线性渐变填充指定两个控制点,画刷在两个控制点之间进行颜色插值。经过建立QLinearGradient对象来设置画刷。
QLinearGradient linearGradient(0,0,200,100);
linearGradient.setColorAt(0,Qt::red);
linearGradient.setColorAt(0.5,Qt::green);
linearGradient.setColorAt(1,Qt::blue);
painter.setBrush(linearGradient);
painter.drawRect(0,0,200,100);
在QGradient构造函数中指定线行填充的两点分别为(0,0),(100,100)。 setColorAt()函数在0-1之间设置指定位置的颜色。
圆形渐变填充
圆形渐变填充须要指定圆心,半径和焦点。画刷在焦点和圆上的全部点之间进行颜色插值,经过建立QRadialGradient对象设置画刷。
QRadialGradient radialGradient(50,50,50,30,30);
radialGradient.setColorAt(0.2,Qt::cyan);
radialGradient.setColorAt(0.8,Qt::yellow);
radialGradient.setColorAt(1,Qt::magenta);
painter.setBrush(radialGradient);
painter.drawEllipse(0,0,100,100);
圆锥渐变填充
圆锥渐变填充指定圆心和开始角,画刷沿圆心逆时针对颜色进行插值,经过建立QConicalGradient对象并设置画刷。
QConicalGradient conicalGradient(60,40,30);
conicalGradient.setColorAt(0,Qt::gray);
conicalGradient.setColorAt(0.4,Qt::darkGreen);
conicalGradient.setColorAt(0.6,Qt::darkMagenta);
conicalGradient.setColorAt(1,Qt::drakBlue);
painter.setBrush(conicalGradient);
painter.drawEllipse(0,0,100,100);
其余填充模式
其余填充模式经过setStyle(Qt::BrushStyle style)函数进行设置。
若是实现自定义填充,可使用QPixmap或者QImage对象进行纹理填充。两种图像分别使用setTexture()和setTextureImage()函数加载纹理。
D、alpha通道
在windows,Mac OSX和有XRender扩展的X11系统上,Qt4可以支持Alpha通道,经过使用Alpha通道,能够实现半透明效果,QColor类中定义了Alpha通道的透明度,0表示彻底透明,255表示彻底不透明。QWidget类有一个属性windowOpacity,经过setWindowOpacity(qreal level)能够设置窗口的透明度。但该属性和Alpha通道的原理并不相同,Qt4在Windows和Mac OS X平台上才支持该属性,但在X11平台上却须要Composite扩展才能工做。(alpha通道使用的是X11的xRender扩展)。
在Qt4中,全部的窗口部件默认都使用双缓冲进行绘图。使用双缓冲,能够减轻绘制的闪烁感。在有些状况下,用户要关闭双缓冲,本身管理绘图。下面的语句设置了窗口部件的Qt::WA_PaintOnScreen属性 ,就关闭了窗口部件的双缓冲。
widget->setAttribute(Qt::WA_PaintOnScreen);
Qt4再也不提供异或笔,组合模式QPainter::CompostionMode_Xor()并非异或笔,Qt4只提供了QRubberBand实现矩形和直线的绘图反馈。要实如今绘图中动态反馈必须使用其余方法。程序中使用双缓冲来解决这个问题。在绘图过程当中,一个缓冲区绘制临时内存,一个缓冲区保存绘制好的内容,最后进行合并。
在交互绘图过程当中,程序将图像缓冲区复制到临时缓冲区,并在临时缓冲区上绘制,绘制完毕在将结果复制到图像缓冲区,若是没有交互复制,则直接将图像缓冲区绘制显示到屏幕上。
绘图路径(painter path)由基本图元(矩形,椭圆,直线,曲线)组成,绘图路径能够是闭合的路径,如矩形和圆,或者是非闭合的路径,如直线和曲线。绘图路径在Qt中使用QPainterPth类表示,提供了绘图操做的容器,可使图形可以复用。绘图路径能够进行填充,显示轮廓和裁剪。要生成可填充的轮廓的绘图路径,可使用QPainterPathStroker类。使用QPainterPath的优势是复杂的图形只需建立一次,就能够屡次使用。QPainterPath对象能够是只有起点的空路径,或者从其余QPainterPath对象复制,建立了QPainterPath对象后,可使用lineTo(),cubicTo(),quadTo() 函数将直线和曲线添加到路径中来,直线和曲线从currentPosition()开始绘制。currentPosition()老是返回最后的子路经绘制的终点。使用moveTo()函数能够在不增长路径的状况下移动currentPositon(),它关闭了一个子路经,开始一个新的子路经。 closeSubPath()也能够关闭当前路径,并从currentPosition()链接一条直线到绘图路径的起点。QPainter可使用 addEllipse(),addPath(),addRect(),addRegion(),
addText()将Qt的一些基本图元加入绘图路径。一个已有的绘图路径能够经过connectPath()函数加入到另外一个绘图路径中。
箭头的绘制代码以下:
QPainterPath path;
path.moveTo(10,100);
path.cubicTo(10,100,100,10,200,70);
path.lineTo(200,50);
path.lineTo(220,80);
path.lineTo(200,110);
path.lineTo(200,90);
path.cubicTo(200,100,100,50,50,100);
QPainter painter(this);
QPen pen(QColor(255,0,0),2);
painter.setPen(pen);
painter.drawPath(path);
Qt提供了两种填充方式,Qt::OddEventFill和Qt::WindingFill。Qt::OddEvent是默认的填充规则,指定QPainterPath使用奇偶填充规则,奇偶填充规则判断一个点是否在路径图形内的方法是从该点画一条水平线到路径外,计算水平线和路径的交点数,若是交点是奇数个则说明该点在路径图形内。QPainterPath还有一些函数能够获取路径信息,如elementAt()函数能够取出指定的子路经元素,isEmpty()函数判断当前路径是否为空。controlPointRect()函数返回路径中全部的点和控制点的矩形,controlPointRect函数运行速度比返回精确包容框boundingRect()函数快得多。contains()函数判断一个点或一个矩形是否在路径内。intersects()判断指定的矩形与路径是否相交。QPainterPath能够将矩形图形转换为其余图形,如使用toFillPolygon(),toFillPolygon(),toSubpathPOlygons()函数将路径转化为多边形。
QPainterPath还可使用文字做为路径。
使用线性渐变填充的文字路径实现代码:
QPainter painter(this);
QLinearGradient linearGrad(QPointF(200,0),QPointF(1000,0));
linearGrad.setColorAt(0,Qt::black);
linearGrad.setColorAt(1,Qt::white);
QFont font("隶书",80);
font.setBold(true);
QPainterPath textPath;
textPath.addText(200,300,font,tr("电子工业出版社"));
painter.setBrush(linearGrad);
painter.drawPath(textPath);
QPaintDevice类是绘制设备的基类,QPainter可以在QPaintDevice子类QWidget,QImage,QPixmap,QGLWidget,QGLPixelBuffer,QPicture,QPrinter,
QSvgGenerator上进行绘制。要实现自定义的绘图设备,必须从QPaintDevice类继承并实现其虚函数QPaintDevice::paintEngine(),paintEngine()将通知QPainter可以在自定义的设备上绘制图形,同时还须要从QPaintEngine类继承自定义的图形绘制引擎。
QWidget是全部用户界面元素的基类,窗口部件是用户界面的原子元素,接受鼠标、键盘、窗口系统的其余事件并在屏幕上绘制本身。
QImage类提供了与硬件无关的图像表示,为直接操做像素提供优化,QImage支持单色、8-bit、32-bit和alpha混合图像,使用QImage的优势在于能够得到平台无关的绘制操做,同时图像能够没必要在GUI线程中处理。
QPixmap是后台显示的图像,为在屏幕上显示图像提供优化,不一样于QImage,QPixmap的图像数据用户不可见,由底层窗口系统管理,为了优化QPixmap图像,Qt提供了QPixmapCache类来存储临时的pixmap。Qt还提供了QPixmap的继承类QBitmap类,QBitmap表示单色的pixmap,主要用来建立自定义的QCursor和QBrush对象,构造QRegion对象,设置pixmap和窗口部件的掩码。
Qt提供了QtOpenGL模块来实现OpenGL操做,QGLWidget容许使用OpenGL API进行绘制。QGLWidget是QWidget的子类,QPainter能够在上面绘制,所以Qt可以利用OpenGL完成绘制操做,如变换和绘制pixmap。
QGLPixelBuffer从QPaintDevice继承,封装了OpenGL pbuffer,使用pbuffer绘制一般是全硬件加速,比使用QPixmap绘制更加迅速。
QGLFrameBufferObject从QPaintDevice继承,QGLFrameBufferObject封装了OpenGL frameBuffer对象,FrameBuffer用来实现后台屏幕绘制,比pixel buffer更好。
QPicture类是可以记录和重演QPainter命令的绘图设备,picture串行化painter的命令为平台无关的格式,QPicture同时也与分辨率无关,如QPicuture可以在不一样的设备上(svg,pdf,ps打印机和屏幕)有同样的显示。QPicture::load()和QPicture::save()函数分别完成载入和存储图像。
QPrinter类是在打印机上绘制的绘图设备,在Windows和MAC OS X上,QPrinter使用内建的打印机驱动程序,在X11上,QPrinter上传postscript代码并发送给lpr,lp或者其余打印程序,QPrinter能够在任意其余QPrintEngine对象上打印,也能够直接生成PDF文件。
QPrintEngine类定义了QPrinter如何和其余打印机系统交互的接口,主要建立本身的打印引擎时,能够从QPaintEngine和QPaintEngine上继承。
主要的绘图成员函数以下:
drawArc() 弧
drawChord() 弦
drawConvexPolygon() 凸多边形
drawEllipse() 椭圆
drawImage() QImage表示的图像
drawLine() 线
drawLines() 多条线
drawPath() 路径
drawPicture() 按QPainter指令绘制
drawPie() 扇形
drawPixmap() QPixmap表示的图像
drawPoint() 点
drawPoints() 多个点
drawPolygon() 多边形
drawPolyline() 多折线
drawRect() 矩形
drawRects() 多个矩形
drawRoundRect() 圆角矩形
drawText() 文字
drawTiledPixmap() 平铺图像
drawLineSegments() 绘制折线
设置好画笔、画刷就可使用绘图函数进行绘图。