窗口繪圖類控件
本節(jié)主要介紹如何實現(xiàn)在窗口中繪圖。在 PyQt5中,一般可以通過QPainter,QPen和 QBrush這三個類來實現(xiàn)繪圖功能。此外,QPixmap的作用是加載并呈現(xiàn)本地圖像,而圖像的呈現(xiàn)本質(zhì)上也是通過繪圖方式實現(xiàn)的,所以QPixmap也可以被視為繪圖的一個類。
1、QPainter
QPainter 類在 QWidget(控件)上執(zhí)行繪圖操作,它是一個繪制工具,為大部分圖形界面提供了高度優(yōu)化的函數(shù),使QPainter類可以繪制從簡單的直線到復(fù)雜的餅圖等。
繪制操作在 QWidget.paintEvent()中完成。繪制方法必須放在 QtGui.QPainter 對象的begin()和 end()之間。QPainter類在控件或其他繪圖設(shè)備上執(zhí)行較低級別的圖形繪制功能,并通過如表1所示的方法進(jìn)行繪制。

還可以設(shè)置畫筆風(fēng)格(PenStyle),這是一個枚舉類,可以由QPainter類繪制。畫筆風(fēng)格如表2所示:

實例演示1:繪制文字
演示在一個窗口中繪制文字
運行程序,顯示效果如下:

代碼分析:
在這個例子中,首先定義可待繪制的文字:
然后,定義了一個繪制事件,所有的繪制操作都發(fā)生在此事件內(nèi)。繪制事件的核心代碼如下:
QtGui.QPainter類負(fù)責(zé)所有低級別的繪制,所有的繪制方法都要放在begin()和end(之間。這個例子放置的是自定義的drawText()方法。
自定義的繪制方法的核心代碼如下:
還有這個的基本原理,新手的話看類和方法里面都沒有直接調(diào)用這個paintEvent,它怎么就能畫出來了?
一個基本的理解,就是這個paintEvent已經(jīng)涉及到pyqt的窗口內(nèi)部機制了,建議別太重度使用,它的使用機制和刷新機制都不是很容易理解的,也就是一個方法的調(diào)用和刷新很可能都不在你的控制下,當(dāng)然如果理解了機制之后再使用就比較容易控制了。
首先是使用,這個paintEvent不能直接調(diào)用,而是需要重寫好相關(guān)內(nèi)部的操作后等待窗口的繪制事件。
繪制的自動觸發(fā)機制如下:
窗口第一次顯示時,
窗口大小調(diào)整時,
窗口切換或遮擋,
以上操作系統(tǒng)會自動產(chǎn)生一個繪圖事件,強制這個paintEvent的運行;
繪制的”手動“觸發(fā)機制:
這里的手動不是手動操作正在運行的窗口程序,而是在程序中使用update或者repaint進(jìn)行重繪
repaint()函數(shù)會強制產(chǎn)生一個即時的重繪事件;
update()函數(shù)只是在Qt下一次處理事件時才調(diào)用一次繪制事件
多次調(diào)用update(),Qt會把連續(xù)多次的繪制事件壓縮成一個單一的繪制事件,這樣可避免閃爍現(xiàn)象。所以建議在需要重繪的時候盡量使用update,在必須實時顯示繪制的時候使用repaint
self.update()
實例演示2:繪制點
在上一節(jié)中使用QPainter繪制了一段文字,文字在屏幕上的顯示是由一個個點(point)組成的,本節(jié)主要講解使用QPainter繪制點。
運行腳本,顯示效果如圖所示:

代碼分析:
在這個例子中,在窗口的工作區(qū)繪制正弦函數(shù)圖形,周期是[-100,100].
畫筆設(shè)置為紅色,使用預(yù)定義的Qt.red顏色。
每次調(diào)整窗口大小時,都會生成一個繪圖事件。使用size()方法得到窗口的當(dāng)前大小,在新的窗口中隨機分布工作區(qū)中的點。
使用drawPoint(方法繪制一個個點。
2、 Qpen
QPen(鋼筆)是一個基本的圖形對象,用于繪制直線、曲線或者給輪廓畫出矩形、橢圓形、多邊形及其他形狀等。
實例演示3:OPen的使用
運行程序,顯示效果如下:

代碼分析:
在這個例子中,使用6種不同的線條樣式繪制了6條線,其中前5條線使用的是預(yù)定義的線條樣式。也可以自定義線條樣式,最后一條線就是使用自定義的線條樣式繪制的。
以下代碼創(chuàng)建了一個QPen對象。為了能更清晰地看清各線之間的差異,將顏色設(shè)置成黑色,寬度設(shè)置為2像素(px)。Qt.SolidLine是預(yù)定義的線條樣式之一。
以下代碼自定義了一種線條樣式。使用Qt.CustomDashLine創(chuàng)建線條樣式,然后調(diào)用setDashPattern()方法使用數(shù)字列表定義樣式。數(shù)字列表的個數(shù)必須是偶數(shù),在本例中數(shù)字列表是[1, 4,5,4],它的個數(shù)是4。在數(shù)字列表中,奇數(shù)位(數(shù)字列表中的第1,3,5等位置)代表一段橫線,偶數(shù)位(數(shù)字列表中的第2,4,6等位置)代表兩段橫線之間的空余距離。在數(shù)字列表中數(shù)字越大,橫線和空余距離就越大。本例中數(shù)字列表[1,4,5,4]代表的意義是:1像素寬度的橫線,4像素寬度的空余距離,5像素寬度的橫線,4像素寬度的空余距離。
3、QBrush
QBrush(畫刷)是一個基本的圖形對象,用于填充如矩形、橢圓形或多邊形等形狀。QBrush有三種類型:預(yù)定義、過渡和紋理圖案。
實例演示4:QBrush的使用
演示使用QBrush在窗口中填充不同背景的矩形,其完整代碼如下:
運行程序,顯示效果如下:

代碼分析:
在這個例子中,在窗口中繪制出9種不同背景填充的矩形。
以下代碼定義了QBrush對象,然后將QPainter對象的畫刷設(shè)置成QBrush對象,并通過調(diào)用drawRect(方法繪制矩形。
4、QPixmap
QPixmap類用于繪圖設(shè)備的圖像顯示,它可以作為一個QPaintDevice對象,也可以加載到一個控件中,通常是標(biāo)簽或按鈕,用于在標(biāo)簽或按鈕上顯示圖像。
QPixmap可以讀取的圖像文件類型有BMP、GIF、JPG、JPEG、PNG、PBM、PGM、PPM、XBM、XPM等。
QPixmap類中的常用方法如表3所示。

樣例前面已經(jīng)介紹很多了,在此不在列舉。核心代碼為: