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);
}