QPainter.drawRectの使い方!!

takkun
どうも!たっくんです!

前回、2つの画像を合成して表示する「カスタムQLabel」をご紹介しましたが、この時に使った「QPainter」の「塗りつぶし(drawRect)」をご紹介したいと思います!(`・ω・´)ゞ

QPainterで画像合成してWidgetに表示する方法!!

2018.01.11

骨組み

「QPainter」を使った描画の処理は、各Widgetの「paintEvent」で行います。「QPainter」のインスタンスを作成したら「begin」を使用して描画を始め、「end」を使用して描画を終了します。

from PySide import QtCore, QtGui

class PainterSample(QtGui.QWidget):
	def paintEvent(self, event):
		painter = QtGui.QPainter(self)
		painter.begin(self)
		
		# ココに、色々な描画処理を書く。
		
		painter.end()
「end」は実行しなくても、QPainterのインスタンスが破棄される時に自動で呼び出されます。

塗りつぶし

塗りつぶしの設定は「setBrush」、線の設定は「setPen」で行い、「drawRect」を使うことで指定した範囲を塗りつぶすことができます(`・ω・´)ゞ

setBrush

色だけ(QtCore.Qt.GlobalColor または QtGui.QColor)」「塗り方だけ(QtCore.Qt.BrushStyle)」「色と塗り方(QtGui.QBrush)」の3種類の設定方法があります。

# 色(QtCore.Qt.GlobalColor)だけ指定(塗り方は変えられません)
painter.setBrush(QtCore.Qt.lightGray)

# 塗り方の指定(色は変えられません)
painter.setBrush(QtCore.Qt.SolidPattern)

# QBrushで指定
painter.setBrush(QtGui.QBrush(QtCore.Qt.lightGray, QtCore.Qt.SolidPattern))

setPen

色だけ(QtCore.Qt.GlobalColor または QtGui.QColor)」「アウトラインのスタイル(QtCore.Qt.PenStyle)」「色とスタイル(QtGui.QPen)」の3種類の設定方法があります。

# 色(QtCore.Qt.GlobalColor)だけ指定(アウトラインのスタイルは変えられません)
painter.setPen(QtCore.Qt.black)

# アウトラインのスタイルだけ指定(色は変えられません)
painter.setPen(QtCore.Qt.SolidLine)

# QPenで指定
painter.setPen(QtGui.QPen(QtCore.Qt.black, 5, QtCore.Qt.SolidLine))

drawRect

塗る範囲をQRectF」「塗る範囲をQRect」「塗る開始座標(x,y)と大きさ(width, height)」の3種類の設定方法があります。

# QRectの指定
painter.drawRect(QtCore.QRect(0, 0, 100, 100))

# QRectFの指定
painter.drawRect(QtCore.QRectF(0.0, 0.0, 100.0, 100.0))

# 開始地点の、大きさの指定
painter.drawRect(0, 0, 320, 160)

描画は後優先

描画の処理をしていると、描画したものが重なってくるときがあると思います!「QPainter」は、基本的に塗り重ねていくので後から描画したものが手前に来ます。

from PySide import QtCore, QtGui

class PainterSample(QtGui.QWidget):
	def paintEvent(self, event):
		painter = QtGui.QPainter(self)
		painter.begin(self)
		
		# 背景を明るいグレーで全面を塗りつぶす
		painter.setBrush(QtCore.Qt.lightGray)
		painter.setPen(QtCore.Qt.NoPen)
		painter.drawRect(self.rect())# self.rectでwidgetのエリアを取得できます。
		
		# 小さい四角形を暗い赤で塗りつぶす
		painter.setBrush(QtCore.Qt.darkRed)
		painter.drawRect(100, 100, 100, 100)
		
		# 小さい四角形を暗い緑で塗りつぶす
		painter.setBrush(QtCore.Qt.darkGreen)
		painter.drawRect(150, 150, 100, 100)
		
window = PainterSample()
window.setWindowFlags(QtCore.Qt.Window)
window.resize(720,405)
window.show()

実行してみると、書いた順番どおり、明るいグレーが一番した、次に赤、そして一番手前に緑が来ます!∠( ゚д゚)/

横3等分に塗り分ける

「self.rect」で取得したwidgetのエリアを元に、3等分の大きさを求めて塗り分けてみます!

from PySide import QtCore, QtGui

class PainterSample(QtGui.QWidget):
	def paintEvent(self, event):
		painter = QtGui.QPainter(self)
		painter.begin(self)
		
		# widgetエリアの取得
		rect = self.rect()
		
		# 左から33.3%の位置
		left30 = rect.width() * 0.333
		
		# 左から66.6%の位置
		left60 = rect.width() * 0.666
		
		# 左側を塗る
		painter.setBrush(QtGui.QColor(29, 122, 161))
		painter.setPen(QtCore.Qt.NoPen)
		painter.drawRect(QtCore.QRectF(0, 0, left30, rect.height()))
		
		# 真ん中を塗る
		painter.setBrush(QtGui.QColor(109, 193, 179))
		painter.setPen(QtCore.Qt.NoPen)
		painter.drawRect(QtCore.QRectF(left30, 0, left60, rect.height()))
		
		# 右側を塗る
		painter.setBrush(QtGui.QColor(177, 219, 189))
		painter.setPen(QtCore.Qt.NoPen)
		painter.drawRect(QtCore.QRectF(left60, 0, rect.width(), rect.height()))
		
window = PainterSample()
window.setWindowFlags(QtCore.Qt.Window)
window.resize(720,405)
window.show()

大きさは「self.rect」をベースにしているので、リサイズしてもキッチリ3等分で塗り分けることができます!(*´ω`*)b