Python Qt GUI設計:QPainter、QPen、QBrush和QPixmap窗口繪圖類(基礎(chǔ)篇—17)
本篇博文主要介紹如何實現(xiàn)在窗口中繪圖,在 PyQt5中,一般可以通過QPainter、QPen、QBrush和QPixmap這四個類來實現(xiàn)繪圖功能。其中,QPixmap的作用是加載并呈現(xiàn)本地圖像,而圖像的呈現(xiàn)本質(zhì)上也是通過繪圖方式實現(xiàn)的。
1
QPainter繪圖類
QPainter類在QWidget(控件)上執(zhí)行繪圖操作,它是一個繪制工具,為大部分圖形界面提供了高度優(yōu)化的函數(shù),使QPainter類可以繪制從簡單的直線到復雜的餅圖等。
繪制操作在QWidget.paintEvent()中完成,繪制方法必須放在QtGui.QPainter對象的begin()和end()之間QPainter類在控件或其他繪圖設備上執(zhí)行較低級別的圖形繪制功能,并通過如下表所示的方法進行繪制:
還可以設置畫筆風格(PenStyle),這是一個枚舉類,可以由QPainter類繪制。畫筆風格如下表所示:
畫筆效果如下所示:
來看看QPainter繪圖類的示例,效果如下所示:
示例中,首先定義了待繪制的文字,代碼如下所示:
self.text = '公眾號:美男子玩編程'然后,定義了一個繪制事件,所有的繪制操作都發(fā)生在此事件內(nèi)。繪制事件代碼如下所示:
def paintEvent(self,event):painter = QPainter(self)painter.begin(self)# 自定義的繪畫方法self.drawText(event, painter)painter.end()
QtGui.QPainter類負責所有低級別的繪制,所有的繪制方法都要放在begin()和end()之間。這個例子放置的是自定義的drawText()方法。自定義的繪制方法代碼如下所示:
def drawText(self, event, qp):# 設置筆的顏色qp.setPen( QColor(168, 34, 3) )# 設置字體qp.setFont( QFont('SimSun', 20))# 畫出文本qp.drawText(event.rect(), Qt.AlignCenter, self.text)
實現(xiàn)代碼如下所示:
import sysfrom PyQt5.QtWidgets import QApplication ,QWidgetfrom PyQt5.QtGui import QPainter ,QColor ,QFontfrom PyQt5.QtCore import Qtclass Drawing(QWidget):def __init__(self,parent=None):super(Drawing,self).__init__(parent)self.setWindowTitle("在窗體中繪畫出文字例子")self.resize(300, 200)self.text = '公眾號:美男子玩編程'def paintEvent(self,event):painter = QPainter(self)painter.begin(self)# 自定義的繪畫方法self.drawText(event, painter)painter.end()def drawText(self, event, qp):# 設置筆的顏色qp.setPen( QColor(168, 34, 3) )# 設置字體qp.setFont( QFont('SimSun', 20))# 畫出文本qp.drawText(event.rect(), Qt.AlignCenter, self.text)if __name__ == "__main__":app = QApplication(sys.argv)demo = Drawing()demo.show()sys.exit(app.exec_())
QPainter繪制文字,實質(zhì)上文字在屏幕上的顯示是由一個個點(point)組成的,來看看QPainter如何繪制點。效果如下所示:
示例中,在窗口的工作區(qū)繪制正弦函數(shù)圖形,周期是[-100,100]。畫筆設置為紅色,使用預定義的Qt.red顏色。每次調(diào)整窗口大小時,都會生成一個繪圖事件。使用size()方法得到窗口的當前大小,在新的窗口中隨機分布工作區(qū)中的點。最后使用drawPoint()方法繪制一個個點。
實現(xiàn)代碼如下所示:
import sys, mathfrom PyQt5.QtWidgets import *from PyQt5.QtGui import *from PyQt5.QtCore import Qtclass Drawing(QWidget):def __init__(self, parent=None):super(Drawing, self).__init__(parent)self.resize(300, 200)self.setWindowTitle("在窗體中畫點")def paintEvent(self, event):qp = QPainter()qp.begin(self)# 自定義畫點方法self.drawPoints(qp)qp.end()def drawPoints(self, qp):qp.setPen( Qt.red)size = self.size()for i in range(1000):# [-100, 100]兩個周期的正弦函數(shù)圖像x = 100 *(-1+2.0*i/1000)+ size.width()/2.0y = -50 * math.sin((x - size.width()/2.0)*math.pi/50) + size.height()/2.0qp.drawPoint(x, y)if __name__ == '__main__':app = QApplication(sys.argv)demo = Drawing()demo.show()sys.exit(app.exec_())
2
QPen繪圖類
QPen(鋼筆)是一個基本的圖形對象,用于繪制直線、曲線或者給輪廓畫出矩形、橢圓形、多邊形及其他形狀等。
來看看QPen繪圖類的示例,效果如下所示:
示例中,使用6種不同的線條樣式繪制了6條線,其中前5條線使用的是預定義的線條樣式。也可以自定義線條樣式,最后一條線就是使用自定義的線條樣式繪制的。
以下代碼創(chuàng)建了一個QPen對象。為了能更清晰地看清各線之間的差異,將顏色設置成黑色,寬度設置為2像素(px)。Qt.SolidLine是預定義的線條樣式之一。
pen = QPen(Qt.black, 2, Qt.SolidLine)以下代碼自定義了一種線條樣式。使用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像素寬度的空余距離。
pen.setStyle(Qt.CustomDashLine)pen.setDashPattern([1, 4, 5, 4])qp.setPen(pen)qp.drawLine(20, 240, 250, 240)
實現(xiàn)代碼如下所示:?
import sysfrom PyQt5.QtWidgets import *from PyQt5.QtGui import *from PyQt5.QtCore import Qtclass Drawing(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setGeometry(300, 300, 280, 270)self.setWindowTitle('鋼筆樣式例子')def paintEvent(self, e):qp = QPainter()qp.begin(self)self.drawLines(qp)qp.end()def drawLines(self, qp):pen = QPen(Qt.black, 2, Qt.SolidLine)qp.setPen(pen)qp.drawLine(20, 40, 250, 40)pen.setStyle(Qt.DashLine)qp.setPen(pen)qp.drawLine(20, 80, 250, 80)pen.setStyle(Qt.DashDotLine)qp.setPen(pen)qp.drawLine(20, 120, 250, 120)pen.setStyle(Qt.DotLine)qp.setPen(pen)qp.drawLine(20, 160, 250, 160)pen.setStyle(Qt.DashDotDotLine)qp.setPen(pen)qp.drawLine(20, 200, 250, 200)pen.setStyle(Qt.CustomDashLine)pen.setDashPattern([1, 4, 5, 4])qp.setPen(pen)qp.drawLine(20, 240, 250, 240)if __name__ == '__main__':app = QApplication(sys.argv)demo = Drawing()demo.show()sys.exit(app.exec_())
3
QBrush繪圖類
QBrush(畫刷)是一個基本的圖形對象,用于填充如矩形、橢圓形或多邊形等形狀。QBrush有三種類型:預定義、過渡和紋理圖案。
來看看QBrush繪圖類的示例,效果如下所示:
在這個例子中,在窗口中繪制出9種不同背景填充的矩形。定義QBrush 對象,然后將QPainter對象的畫刷設置成QBrush 對象,并通過調(diào)用drawRect()方法繪制矩形。
實現(xiàn)代碼如下所示:
import sysfrom PyQt5.QtWidgets import *from PyQt5.QtGui import *from PyQt5.QtCore import Qtclass Drawing(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setGeometry(300, 300, 365, 280)self.setWindowTitle('畫刷例子')self.show()def paintEvent(self, e):qp = QPainter()qp.begin(self)self.drawLines(qp)qp.end()def drawLines(self, qp):brush = QBrush(Qt.SolidPattern)qp.setBrush(brush)qp.drawRect(10, 15, 90, 60)brush = QBrush(Qt.Dense1Pattern)qp.setBrush(brush)qp.drawRect(130, 15, 90, 60)brush = QBrush(Qt.Dense2Pattern)qp.setBrush(brush)qp.drawRect(250, 15, 90, 60)brush = QBrush(Qt.Dense3Pattern)qp.setBrush(brush)qp.drawRect(10, 105, 90, 60)brush = QBrush(Qt.DiagCrossPattern)qp.setBrush(brush)qp.drawRect(10, 105, 90, 60)brush = QBrush(Qt.Dense5Pattern)qp.setBrush(brush)qp.drawRect(130, 105, 90, 60)brush = QBrush(Qt.Dense6Pattern)qp.setBrush(brush)qp.drawRect(250, 105, 90, 60)brush = QBrush(Qt.HorPattern)qp.setBrush(brush)qp.drawRect(10, 195, 90, 60)brush = QBrush(Qt.VerPattern)qp.setBrush(brush)qp.drawRect(130, 195, 90, 60)brush = QBrush(Qt.BDiagPattern)qp.setBrush(brush)qp.drawRect(250, 195, 90, 60)if __name__ == '__main__':app = QApplication(sys.argv)demo = Drawing()demo.show()sys.exit(app.exec_())
4
QPixmap繪圖類
QPixmap類用于繪圖設備的圖像顯示,它可以作為一個QPaintDevice對象,也可以加載到一個控件中,通常是標簽或按鈕,用于在標簽或按鈕上顯示圖像。
QPixmap可以讀取的圖像文件類型有BMP、GIF、JPG、JPEG、PNG、PBM、PGM、PPM、XBM、XPM等。
QPixmap類中的常用方法如下表所示:
示例中,使用setPixmap()將圖像顯示在QLabel上。實現(xiàn)代碼如下所示:
實現(xiàn)代碼如下所示:
import sysfrom PyQt5.QtCore import *from PyQt5.QtGui import *from PyQt5.QtWidgets import *if __name__ == '__main__':app = QApplication(sys.argv)win = QWidget()lab1 = QLabel()lab1.setPixmap(QPixmap("./2.jpg"))vbox=QVBoxLayout()vbox.addWidget(lab1)win.setLayout(vbox)win.setWindowTitle("QPixmap 例子")win.show()sys.exit(app.exec_())
往期推薦

