天天看點

學習QT之QT繪圖原理詳解

一、Qt繪制事件

當應用程式收到繪制事件時,就會調用​

​QWidget::paintEvent()​

​,該函數就是繪制視窗的地方。

有兩種方法要求重繪一個視窗

  1. ​update()​

    ​ --把重繪事件添加到事件隊列中
  • 重複調用​

    ​update()​

    ​會被Qt合并為一次
  • 不會産生圖像的閃爍
  • 可帶參數指定重繪某個區域
  1. ​repaint()​

    ​ --立即産生繪制事件
  • 一般情況下不推薦使用此方法
  • 隻使用在需要立即重繪的特效情況下
  • 可帶參數指定重繪某個區域

為了處理繪制事件,隻需要重寫​

​paintEvent()​

​​函數,并在該函數中執行個體化一個​

​QPainter​

​對象進行繪制。

class MyWidget : public QWidget
{
    ...
protected:
    void paintEvent(QPaintEvent *);
}

void MyWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    ...
}      
學習QT之QT繪圖原理詳解

基本繪制

  • ​QPainter​

    ​類提供繪制操作,其構造函數原型為:
QPainter(QPaintDevice *device);      
  • ​QPaintDevice​

    ​代表繪制2D圖像的畫布;
  • 如下繼承​

    ​QPaintDevice​

    ​的類對象都可用于​

    ​QPainter​

    ​繪制
QWidget、QImage、QPixmap、QPicture、QPrinter、QSvgGenerator、
QGLPixelBuffer、QGLFrameBufferObject      

二、Qt 2D繪圖

QPainter

  1. 線和輪廓都可以用畫筆(QPen)進行繪制,用畫刷(QBrush)進行填充;
  2. 字型使用​

    ​QFont​

    ​類定義,當繪制文字時,Qt使用指定字型的屬性,如果沒有比對的字型,Qt将使用最接近的字型;
  3. 通常情況下,​

    ​QPainter​

    ​​以預設的坐标系統進行繪制,也可以用​

    ​QMatrix​

    ​類對坐标進行變換;
  4. 當繪制是,可以使用​

    ​QPainter::RenderHint​

    ​來告訴繪圖引擎是否棄用反鋸齒功能使圖變得平滑;
  5. ​QPainter::RenderHint​

    ​的可取值:
  • ​QPainter::Antialiasing​

    ​:告訴繪圖引擎應該在可能的情況下進行邊的反鋸齒繪制
  • ​QPainter::TextAntialiasing​

    ​:盡可能的情況下文字的反鋸齒繪制
  • ​QPainter::SmoothPixmapTransform​

    ​:使用平滑的pixmap變換算法(雙線性插值算法),而不是近鄰插值算法;

QPainter的繪圖函數總結如下:

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

三、畫筆

  • 畫筆的屬性包括線型、線寬、顔色等。畫筆屬性可以在構造函數中指定,也可以使用​

    ​setStyle()​

    ​​,​

    ​setWidth()​

    ​​,​

    ​setBrush()​

    ​​,​

    ​setCapStyle()​

    ​​,​

    ​setJoinStyle()​

    ​等函數設定;
  • Qt中,使用Qt::PenStyle定義了6中畫筆風格,分别是:
學習QT之QT繪圖原理詳解

​ 還可以自定義線風格(​

​Qt::CustomDashLine​

​​),需要使用QPen的​

​setDashPattern()​

​函數來設定自定義風格。

端點風格(cap style)

  • 端點風格決定了線的端點樣式,隻對線寬大于1的線有效。
  • Qt定義了三種端點風格用枚舉類型​

    ​Qt::PenCapStyle​

    ​表示,分别為:
學習QT之QT繪圖原理詳解

​Qt::PenCapStyle​

說明
Qt::SquareCap 表示線上條的頂點處是方形的,且線條繪制的區域包括了端點,并且再往外延伸半個線寬的長度
Qt::FlatCap 表示線上條的頂點處是方形的,但線條繪制區域不包括端點在内
Qt::RoundCap 表示線上條的頂點處是圓形的,且線條繪制區域包含了端點。

連接配接風格(join style)

  • 連接配接風格是兩條線如何連接配接,連接配接風格對線寬大于等于1的線有效;
  • Qt定義了四種連接配接方式,用枚舉類型​

    ​Qt::PenStyle​

    ​表示。分别是:
  • 學習QT之QT繪圖原理詳解

​Qt::PenStyle​

說明
Qt::BevelJoin 指兩條線的中心線頂點相彙,相連處依然保留線條各自的方形頂端
Qt::MiterJoin 指兩條線的中心線頂點相彙,相連處線條延長到線的外側彙集至點,形成一個尖頂的連接配接
Qt::RoundJoin 指兩條線的中心線頂點相彙,相連處以圓弧形連接配接

四、畫刷

  1. 在Qt中圖形使用​

    ​QBrush​

    ​進行填充,畫刷包括填充顔色和風格(填充模式)。
  2. 在Qt中,顔色使用​

    ​QColor​

    ​​類表示,​

    ​QColor​

    ​支援RGB、HSV、CMYK顔色模型。QColor還支援alpha混合的輪廓和填充。
  • RGB是面向硬體的模型。顔色有紅綠藍三種基色混合而成。
  • HSV/HSL模型比較符合人對顔色的感覺,由色調(0-359),飽和度(0-255),亮度(0-255)組成,主要用于顔色選擇器。
  • CMYK由青、洋紅、黃、黑四種基色組成。主要用于列印機等硬體拷貝裝置上。每個顔色分量的取值是0-255。
  1. 基本模式填充包括有各種點、線組合的模式。

QColor

​QColor​

​​的構造函數:​

​QColor(int r,int g,int b,int a)​

其中 參數a(alpha)是控制透明度的,取值範圍為0-255;0為完全透明,255為不透明。

顔色還可以使用如下函數進行微調

QColor::lighter(int factor)
QColor::darker(int factor)      

QRgb

  • QRgb類可以用于儲存顔色值,可與QColor互相轉換擷取32-bit的RGB顔色值+alpha值。
  • 建立新顔色
QRgb orange = qRgb(255,127,0);
QRgb overlay = qRgb(255,0,0,100);      
  • 擷取單獨某個顔色值:qRed,qGreen,qBlue,qAlpha
int red = qRed(orange);      
  • 擷取灰階值
int gray = qGray(orange);      

模式畫刷

模式化畫刷構造函數​

​QBrush(const QColor *color,Qt::BrushStyle style)​

​,具體見下圖:

五、漸變填充

  • Qt提供了漸變填充的畫刷,漸變填充包括兩個要素:顔色的變化和路徑的變化
  • 顔色變化可以指定從一種顔色漸變到另外一種顔色。
  • 路徑變化指在路徑上指定一些點的顔色進行分段漸變。
  • Qt中,提供了三種漸變填充
  • 線性(QLinearGradient)
  • 圓形(QRadialGradient)
  • 圓錐漸變(QConicalGradient)
  • 所有的類都從QGradient類繼承
  • 構造漸變填充的畫刷
QBrush b = QBrush(QRadialGradient(...));      
  • 從圖形的起點到終點,以從0至1的比例漸變填充
QGradient::setColorAt(qreal pos,QColor color);      
  • 完成0-1範圍的填充後,後續顔色鋪開的方式可以不同,通過​

    ​setSpread()​

    ​函數來設定

1、線性漸變填充

  • 線性漸變填充指定兩個控制點,畫刷在兩個控制點之間進行顔色插值。
  • 通過建立​

    ​QLinearGradient​

    ​對象來設定畫刷。
QPainter painter(this);
QLinearGradient g(0,0,100,100);
g.setColorAt(0.0,Qt::white);
g.setColorAt(1.0,Qt::blue);
painter.setBrush(g);
p.drawRect(0,0,100,100);      
  • 在​

    ​QGradient​

    ​構造函數中指定線性填充的兩點分别為(0,0),(100,100)。
  • ​setColorAt()​

    ​函數在0-1之間設定指定位置的顔色。

2、圓形漸變填充

  • 圓形漸變填充需要指定圓心、半徑和焦點
QRadialGradient(qreal cx,qreal cy,qreal radius,qreal fx,qreal fy);      
  • 畫刷在焦點和圓上的所有點之間進行顔色插值。
  • 建立​

    ​QRadialGradient​

    ​對象設定畫刷
QPainter painter(this);
QRadialGradient radialGradient(50,50,50,30,30);
radialGradient.setColorAt(0.0,Qt::white);
radialGradient.setColorAt(1.0,Qt::blue);
painter.setBrush(radialGradient);
painter.drawRect(0,0,100,100);      

3、圓錐漸變填充

  • 圓錐漸變填充指定圓形和開始角
QConicalGradient(qreal cx,qreal cy,qreal angle);      
  • 畫刷沿圓心逆時針對顔色進行插值
  • 建立​

    ​QConicalGradient​

    ​對象并設定畫刷
QPainter painter(this);
QConicalGradient conicalGradient(50,50,90);
conicalGradient.setColorAt(0,Qt::white);
conicalGradient.setColorAt(1,Qt::blue);
painter.setBrush(conicalGradient);
painter.drawRect(0,0,100,100);      
  • 為了實作自定義填充,還可以使用QPixmap或者QImage對象進行紋理填充。兩種圖像分别使用​

    ​setTexture()​

    ​和​

    ​setTextureImage()​

    ​函數加載紋理。

繼續閱讀