Qt利用QPainter實(shí)現(xiàn)基本繪圖的示例詳解
簡(jiǎn)述
Qt 中提供了強(qiáng)大的 2D 繪圖系統(tǒng),可以使用相同的 API 在屏幕和繪圖設(shè)備上進(jìn)行繪制,它主要基于QPainter、QPaintDevice 和 QPaintEngine 這三個(gè)類(lèi)。
- QPainter 用于執(zhí)行繪圖操作,其提供的 API 在 GUI 或 QImage、QOpenGLPaintDevice、QWidget 和QPaintDevice 顯示圖形(線(xiàn)、形狀、漸變等)、文本和圖像。
- QPaintDevice 不直接繪制物理顯示畫(huà)面,而利用邏輯界面的中間媒介。例如,繪制矩形圖形時(shí),為了將對(duì)象繪制到 QWidget、QGLPixelBuffer、QImage、QPixmap、QPicture 等多種界面中間,必須使用 QPaintDevice。
- QPaintEngine 提供了一些接口,可用于 QPainter 在不同的設(shè)備上進(jìn)行繪制。
繪圖系統(tǒng)由 QPainter 完成具體的繪制操作,QPainter 類(lèi)提供了大量高度優(yōu)化的函數(shù)來(lái)完成 GUI 編程所需要的大部分繪制工作。它可以繪制一切想要的圖形,從最簡(jiǎn)單的一條直線(xiàn)到其他任何復(fù)雜的圖形,例如:點(diǎn)、線(xiàn)、矩形、弧形、餅狀圖、多邊形、貝塞爾弧線(xiàn)等。此外,QPainter 也支持一些高級(jí)特性,例如反走樣(針對(duì)文字和圖形邊緣)、像素混合、漸變填充和矢量路徑等,QPainter 也支持線(xiàn)性變換,例如平移、旋轉(zhuǎn)、縮放。
QPainter 可以在繼承自 QPaintDevice 類(lèi)的任何對(duì)象上進(jìn)行繪制操作。QPainter 也可以與 QPrinter 一起使用來(lái)打印文件和創(chuàng)建 PDF 文檔。這意味著通??梢杂孟嗤拇a在屏幕上顯示數(shù)據(jù),也可以生成打印形式的報(bào)告。
QPainter 一般在部件的繪圖事件 paintEvent() 中進(jìn)行繪制,首先創(chuàng)建 QPainter 對(duì)象,然后進(jìn)行圖形的繪制,最后記得銷(xiāo)毀 QPainter 對(duì)象。當(dāng)窗口程序需要升級(jí)或者重新繪制時(shí),調(diào)用此成員函數(shù)。使用 repaint()和 update() 后,調(diào)用函數(shù) paintEvent()。
繪制文本

void MainWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event);
QPainter painter(this);
// 設(shè)置畫(huà)筆顏色
painter.setPen(QColor(0, 160, 230));
// 設(shè)置字體:微軟雅黑、點(diǎn)大小50、斜體
QFont font;
font.setFamily("Microsoft YaHei");
font.setPointSize(50);
font.setItalic(true);
painter.setFont(font);
// 繪制文本
painter.drawText(rect(), Qt::AlignCenter, "Qt");
}首先為該部件創(chuàng)建了一個(gè) QPainter 對(duì)象,用于后面的繪制。使用 setPen() 來(lái)設(shè)置畫(huà)筆的顏色(淡藍(lán)色)。通過(guò)使用 QFont 來(lái)構(gòu)建我們想要的字體,setFamily()設(shè)置字體為微軟雅黑、setPointSize() 設(shè)置點(diǎn)大小30、setItalic() 設(shè)置斜體, 然后通過(guò) setFont() 來(lái)設(shè)置字體,最后調(diào)用 drawText() 來(lái)實(shí)現(xiàn)文本的繪制,這里的 rect() 是指當(dāng)前窗體的顯示區(qū)域,Qt::AlignCenter 指文本居中繪制。
繪制直線(xiàn)

void MainWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event);
QPainter painter(this);
// 反走樣
painter.setRenderHint(QPainter::Antialiasing, true);
// 設(shè)置畫(huà)筆顏色
painter.setPen(QColor(0, 160, 230));
// 繪制直線(xiàn)
painter.drawLine(QPointF(0, height()), QPointF(width() / 2, height() / 2));
}
首先我們通過(guò) setRenderHint() 來(lái)設(shè)置反走樣,要么繪制出來(lái)的線(xiàn)條會(huì)出現(xiàn)鋸齒,調(diào)用 setPen() 來(lái)設(shè)置畫(huà)筆顏色(淡藍(lán)色)。最后調(diào)用 drawLine() 來(lái)實(shí)現(xiàn)直線(xiàn)的繪制,其中 QPointF(0, height()) 是指直線(xiàn)的起點(diǎn)坐標(biāo)、QPointF(width() / 2, height() / 2) 是指直線(xiàn)的終點(diǎn)坐標(biāo)。
繪制矩形
void MainWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event);
QPainter painter(this);
// 反走樣
painter.setRenderHint(QPainter::Antialiasing, true);
// 設(shè)置畫(huà)筆顏色、寬度
painter.setPen(QPen(QColor(0, 160, 230), 2));
// 設(shè)置畫(huà)刷顏色
painter.setBrush(QColor(255, 160, 90));
painter.drawRect(50, 50, 160, 100);
}
首先我們使用 setPen() 來(lái)設(shè)置畫(huà)筆顏色(淡藍(lán)色)、寬度(2 像素),用來(lái)設(shè)置矩形區(qū)域的邊框。然后使用setBrush() 來(lái)設(shè)置畫(huà)刷顏色(橙色),用來(lái)填充矩形區(qū)域,最后調(diào)用 drawRect() 來(lái)實(shí)現(xiàn)矩形的繪制,其中參數(shù)依次順序?yàn)?x、y、w、h,是指區(qū)域從 x 為 50,y 為 50 的坐標(biāo)點(diǎn)起,寬度為 160,高度為 100 的矩形。
繪制弧線(xiàn)

void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
// 矩形
QRectF rect(90.0, 90.0, 80.0, 90.0);
// 起始角度
int startAngle = 30 * 16;
// 跨越度數(shù)
int spanAngle = 120 * 16;
QPainter painter(this);
// 反走樣
painter.setRenderHint(QPainter::Antialiasing, true);
// 設(shè)置畫(huà)筆顏色、寬度
painter.setPen(QPen(QColor(0, 160, 230), 2));
// 繪制弧線(xiàn)
painter.drawArc(rect, startAngle, spanAngle);
}畫(huà)弧線(xiàn)時(shí),角度被分成了十六分之一,就是說(shuō),如果要 30 度,就需是 30*16。它有起始角度和跨度,還有位置矩形,所以,要想畫(huà)出自己想要的弧線(xiàn),就需要大概估算出各個(gè)參數(shù)的預(yù)估值。
繪制橢圓

void MainWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event);
QPainter painter(this);
// 反走樣
painter.setRenderHint(QPainter::Antialiasing, true);
// 設(shè)置畫(huà)筆顏色、寬度
painter.setPen(QPen(QColor(0, 160, 230), 2));
// 繪制橢圓
painter.drawEllipse(QPointF(120, 60), 50, 20);
// 設(shè)置畫(huà)刷顏色
painter.setBrush(QColor(255, 160, 90));
// 繪制圓
painter.drawEllipse(QPointF(120, 140), 40, 40);
}這里我們繪制了一個(gè)橢圓和一個(gè)圓形,都是調(diào)用 drawEllipse() 接口,我們可以很輕易的發(fā)現(xiàn),如果為橢圓的時(shí)候,后面兩個(gè)參數(shù)不一樣,圓形則相同。首先我們來(lái)看第一個(gè)參數(shù) QPointF 是指橢圓的中心點(diǎn)相對(duì)當(dāng)前窗體 QPoint(0, 0) 點(diǎn)的位置,后面的參數(shù)指橢圓的 x 軸及 y 軸的半徑。
繪制多邊形

void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
// 反走樣
painter.setRenderHint(QPainter::Antialiasing, true);
// 設(shè)置畫(huà)筆顏色
painter.setPen(QColor(0, 160, 230));
// 各個(gè)點(diǎn)的坐標(biāo)
static const QPointF points[4] = {QPointF(30, 40), QPointF(60, 150), QPointF(150, 160), QPointF(220, 100)};
// 繪制多邊形
painter.drawPolygon(points, 4);
}首先,我們定義一個(gè)個(gè)坐標(biāo)點(diǎn)的位置,這里有四個(gè)點(diǎn),分別為:QPointF(30, 40)、QPointF(60, 150)、QPointF(150, 160)、 QPointF(220, 100),然后調(diào)用 drawPolygon() 將各個(gè)點(diǎn)連接起來(lái),繪制為多邊形。
繪制圖片

void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
// 反走樣
painter.setRenderHint(QPainter::Antialiasing, true);
// 繪制圖標(biāo)
painter.drawPixmap(rect(), QPixmap(":/Images/logo"));
}通過(guò) drawPixmap() 來(lái)繪制圖片,我們可以指定圖片繪制的區(qū)域 QRect,這里為整個(gè)界面的區(qū)域,當(dāng)界面伸縮的時(shí)候,圖片也會(huì)跟著伸縮。
以上就是Qt利用QPainter實(shí)現(xiàn)基本繪圖的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Qt QPainter繪圖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++發(fā)送HTTP請(qǐng)求的實(shí)現(xiàn)代碼
這篇文章主要介紹了C++發(fā)送HTTP請(qǐng)求的實(shí)現(xiàn)代碼,需要的朋友可以參考下2014-06-06
C++ API功能設(shè)計(jì)的實(shí)現(xiàn)
C++ API中看似很小的修改,都可能會(huì)影響到生成的對(duì)象和庫(kù)文件的二進(jìn)制表示,如果客戶(hù)想替換共享庫(kù)使之工作,就不能簡(jiǎn)單的替換庫(kù)文件了事,而往往需要重新編譯2022-08-08
VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼
這篇文章主要介紹了VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)(dll)(文末附源碼),本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
C++命名空間?缺省參數(shù)?const總結(jié)?引用總結(jié)?內(nèi)聯(lián)函數(shù)?auto關(guān)鍵字詳解
這篇文章主要介紹了C++命名空間?缺省參數(shù)?const總結(jié)?引用總結(jié)?內(nèi)聯(lián)函數(shù)?auto關(guān)鍵字詳解的相關(guān)資料,需要的朋友可以參考下2023-01-01
模擬鼠標(biāo)事件的實(shí)現(xiàn)思路及代碼
這篇文章主要介紹了模擬鼠標(biāo)事件的實(shí)現(xiàn)思路及代碼,有需要的朋友可以參考一下2013-12-12
C++實(shí)現(xiàn)LeetCode(90.子集合之二)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(90.子集合之二),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07

