Qt QPainter 基礎繪圖


Qt的繪圖系統允許使用相同的API在屏幕和打印設備上進行繪制。整個繪圖系統基於QPainter,QPainterDevice和QPaintEngine三個類。

QPainter用來執行繪制的操作;QPaintDevice是一個二維空間的抽象,這個二維空間可以由QPainter在上面進行繪制;QPaintEngine提供了畫筆painter在不同的設備上進行繪制的統一的接口。

它可以繪制一切想要的圖形,從最簡單的一條直線到其他任何復雜的圖形,例如:點、線、矩形、弧形、餅狀圖、多邊形、貝塞爾弧線等。

此外,QPainter 也支持一些高級特性,例如反走樣(針對文字和圖形邊緣)、像素混合、漸變填充和矢量路徑等,QPainter 也支持線性變換,例如平移、旋轉、縮放。

首先簡單介紹一下坐標系統:QT中的窗口都有的默認的坐標原點(0,0),位於屏幕的左上角,X軸正方向是水平向右,Y軸正方向是豎直向下,相反為負。

x:窗口左上角x坐標
y:窗口左上角y坐標
width:窗口長度
height:窗口高度

一個繪圖工具的使用步驟常為:(1)構造一個繪圖工具(2)設置字體、畫筆、畫刷等等參數(3)繪圖(4)銷毀繪圖工具

繪制的內容會以背景的形式出現在窗口中,線和輪廓都可以用畫筆QPen進行繪制,畫刷QBrush進行填充,字體可以使用QFont類定義。

大量的資料在QT提供的官方文檔里有介紹,也可以直接看看。

我們先來看幾個常見的圖像,我用的是QT5.9.0,首先在頭文件中加入

#include <QPainter>

以及聲明函數

protected:void paintEvent(QPaintEvent *);//重繪事件處理函數

1.繪制直線

void MainWindow::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);//Q_UNUSED() 沒有實質性的作用,用來避免編譯器警告

    QPainter painter(this);//this為繪圖設備,即表明在該部件上進行繪制

    painter.drawLine(0, 0, 200, 200);
}

2.繪制矩形

painter.drawRect(50, 50, 150, 150);//x,y,w,h 

3.繪制橢圓

painter.drawEllipse(100, 100, 100, 80); //x,y,w,h

4.繪制扇形

QRectF rect(50, 50, 500, 500);
int startAngle = 0 * 16;//扇形起始角度(0°) startAngle: 開始的角度,單位是十六分之一度
int spanAngle = 120 * 16;//扇形覆蓋范圍(120°) spanAngle: 覆蓋的角度,單位是十六分之一度
painter.drawPie(rect, startAngle, spanAngle);//繪制圓心為包圍矩形的正中心,角度的正方向是逆時針方向

坐標系變換是利用變換矩陣來進行的,我們可以利用QTransform類來設置變換矩陣,QPainter類提供了對坐標系的平移,縮放,旋轉,扭曲等變換函數。

如利用translate()函數進行平移變換。其實就是改變坐標的中心。

void MainWindow::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);//Q_UNUSED() 沒有實質性的作用,用來避免編譯器警告

    QPainter painter(this);//this為繪圖設備,即表明在該部件上進行繪制

    painter.setBrush(Qt::blue);

    painter.drawRect(0, 0, 100, 100);

    painter.translate(100, 100); //將當前坐標系下的點(100,100)設為原點

    painter.setBrush(Qt::green);

    painter.drawRect(0, 0, 100, 100);
}

利用scale()函數進行比例變換,實現放大縮小。(和css很像)

void MainWindow::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);//Q_UNUSED() 沒有實質性的作用,用來避免編譯器警告

    QPainter painter(this);//this為繪圖設備,即表明在該部件上進行繪制

    painter.setBrush(Qt::blue);

    painter.drawRect(0, 0, 100, 100);

    painter.translate(100, 0);//將中心移到(100,0)
 
    painter.scale(2, 2); //在x軸和y軸方向擴大2倍,小於1為縮小

    painter.setBrush(Qt::green);

    painter.drawRect(0, 0, 100, 100);
}

利用rotate()函數進行翻轉變換。 注意和上圖的區別

void MainWindow::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);//Q_UNUSED() 沒有實質性的作用,用來避免編譯器警告

    QPainter painter(this);//this為繪圖設備,即表明在該部件上進行繪制

    painter.setBrush(Qt::blue);

    painter.drawRect(0, 0, 100, 100);

    painter.translate(100, 100);//將中心移到(100,100)

    painter.rotate(30);//旋轉30°

    painter.setBrush(Qt::green);

    painter.drawRect(0, 0, 100, 100);
}

利用shear()函數就行扭曲變換。

void MainWindow::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);//Q_UNUSED() 沒有實質性的作用,用來避免編譯器警告

    QPainter painter(this);//this為繪圖設備,即表明在該部件上進行繪制

    painter.setBrush(Qt::blue);

    painter.drawRect(0, 0, 100, 100);

    painter.translate(100, 100);//將中心平移到(100,100)

    painter.shear(0, 1);   //x方向保持不變,y軸發生變化

    painter.setBrush(Qt::green);

    painter.drawRect(0, 0, 100, 100);
}

坐標系的保存與恢復

繪圖過程中可以先利用save()函數來保存坐標系現在的狀態,然后進行變換操作,操作完之后,再用restore()函數將以前的坐標系狀態恢復。

void MainWindow::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);//Q_UNUSED() 沒有實質性的作用,用來避免編譯器警告

    QPainter painter(this);//this為繪圖設備,即表明在該部件上進行繪制

    painter.save();

    painter.translate(100, 100);//將中心移到(100,100)

    painter.setBrush(Qt::blue);

    painter.drawRect(0, 0, 100, 100);

    painter.restore();

    painter.setBrush(Qt::green);

    painter.drawRect(0, 0, 100, 100);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM