QT開發(十四)——QT繪圖系統

QT開發(十四)——QT繪圖系統

1、QT繪圖原理

    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

1、重寫重繪事件處理函數實現繪圖

重繪事件處理函數:框架

    void QWidget::paintEvent ( QPaintEvent * event )ide

    基礎部件類Qwidget提供的paintEvent函數,是虛函數;Qwidget的子類要使用paintEvent函數必須從新實現。三種狀況會發生重繪事件調用paintEvent函數: svg

    A、當窗口部件第一次顯示時,系統會自動產生一個繪圖事件函數

    B、repaint()與update()函數被調用時工具

    C、當窗口部件被其餘部件遮擋,而後又再次顯示出來時,就會對隱藏的區域產生一個重繪事件post

    D、從新調整窗口大小時

二、經過事件過濾器實現重繪

 

 

2、繪圖工具

    繪圖時須要先定義一個QPainter類對象,繪圖工具可使Qpen(畫筆)QBrush(畫刷)Qpen(畫筆)來繪製輪廓線QBrush(畫刷)用來填充,使用QPen寫文本時還能夠指定字體(QFont類)

一、QPen畫筆

畫筆的屬性包括線型,線寬,顏色等。

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枚舉定義。

wKioL1gZ_s_SSzThAADgB27T7KU780.png

    C、畫筆的端點風格( Qt::PenCapStyle)
    畫筆端點風格決定了線的端點樣式,只對線寬大於1的線有效。Qt使用枚舉定義了三種端點風格分別爲Qt::SqureCap,QT::FlatCap,Qt::RoundCap

wKiom1gZ_vKDuzY8AAAmvcAG6lI859.png

    D、畫筆鏈接風格(Qt::PenJoinStyle)
    畫筆鏈接風格是兩條線如何鏈接,鏈接風格對線寬大於等於1的線有效。Qt使用枚舉定義了四種鏈接類型分別Qt::MiterJoinQt::BevelJoinQt::RoundJoinQt::SvgMiterJoin

wKiom1gZ_xPyW3KFAAC0euVIEU8859.png

二、QBrush畫刷

    在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,不進行任何填充;填充模式包括基本填充模式,漸變填充,和紋理填充模式。不一樣的填充模式顯示效果以下:

wKioL1gZ_z6xC9IxAACL01fLQdk546.png

    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擴展)

3雙緩衝繪圖

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::WindingFillQt::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);

3、繪圖設備

    QPaintDevice類是繪製設備的基類QPainter可以在QPaintDevice子類QWidget,QImage,QPixmap,QGLWidget,QGLPixelBuffer,QPicture,QPrinter
QSvgGenerator上進行繪製。要實現自定義的繪圖設備,必須從QPaintDevice類繼承並實現其虛函數QPaintDevice::paintEngine()paintEngine()將通知QPainter可以在自定義的設備上繪製圖形,同時還須要從QPaintEngine類繼承自定義的圖形繪製引擎。

1QWidget

QWidget是全部用戶界面元素的基類,窗口部件用戶界面的原子元素,接受鼠標鍵盤窗口系統的其餘事件並在屏幕上繪製本身。

2QImage

QImage類提供了與硬件無關的圖像表示,爲直接操做像素提供優化,QImage支持單色8-bit32-bit和alpha混合圖像,使用QImage的優勢在於能夠得到平臺無關的繪製操做,同時圖像能夠沒必要在GUI線程中處理。

3QPixmap

QPixmap後臺顯示的圖像,爲在屏幕上顯示圖像提供優化,不一樣於QImage,QPixmap的圖像數據用戶不可見,由底層窗口系統管理,爲了優化QPixmap圖像,Qt提供了QPixmapCache類來存儲臨時的pixmapQt還提供了QPixmap的繼承類QBitmap類,QBitmap表示單色的pixmap,主要用來建立自定義的QCursor和QBrush對象,構造QRegion對象,設置pixmap和窗口部件的掩碼。

4OPenGLWidget

Qt提供了QtOpenGL模塊來實現OpenGL操做,QGLWidget容許使用OpenGL API進行繪製。QGLWidgetQWidget的子類,QPainter能夠在上面繪製,所以Qt可以利用OpenGL完成繪製操做,如變換和繪製pixmap

5QGLPixelBuffer

QGLPixelBuffer從QPaintDevice繼承,封裝了OpenGL pbuffer使用pbuffer繪製一般全硬件加速,比使用QPixmap繪製更迅速。

6QGLFrameBufferObject

QGLFrameBufferObject從QPaintDevice繼承,QGLFrameBufferObject封裝了OpenGL frameBuffer對象,FrameBuffer用來實現後臺屏幕繪製,比pixel buffer更好。

7QPicture

QPicture類可以記錄和重演QPainter命令的繪圖設備,picture串行化painter的命令爲平臺無關的格式,QPicture同時也分辨率無關,如QPicuture可以在不一樣的設備上(svg,pdf,ps打印機和屏幕)有同樣的顯示。QPicture::load()和QPicture::save()函數分別完成載入和存儲圖像。

8QPrinter

QPrinter類在打印機上繪製的繪圖設備,在Windows和MAC OS X上,QPrinter使用內建的打印機驅動程序,在X11上,QPrinter上傳postscript代碼併發送給lpr,lp或者其餘打印程序,QPrinter能夠在任意其餘QPrintEngine對象上打印,也能夠直接生成PDF文件。
    QPrintEngine類定義了QPrinter如何和其餘打印機系統交互的接口,主要建立本身的打印引擎時,能夠從QPaintEngine和QPaintEngine上繼承。

4、QPainter類成員函數

    主要的繪圖成員函數以下:

    drawArc()                                  弧
    drawChord()                                弦
    drawConvexPolygon()                        凸多邊形
    drawEllipse()                              橢圓
    drawImage()                                QImage表示的圖像
    drawLine()                                 線
    drawLines()                                多條線
    drawPath()                                 路徑
    drawPicture()                              按QPainter指令繪製
    drawPie()                                  扇形
    drawPixmap()                               QPixmap表示的圖像
    drawPoint()                                點
    drawPoints()                               多個點
    drawPolygon()                              多邊形
    drawPolyline()                             多折線
    drawRect()                                 矩形
    drawRects()                                多個矩形
    drawRoundRect()                            圓角矩形
    drawText()                                 文字
    drawTiledPixmap()                          平鋪圖像
    drawLineSegments()                         繪製折線

    設置好畫筆、畫刷就可使用繪圖函數進行繪圖。

相關文章
相關標籤/搜索