QPainterのtranslateとrotateを使う方法!!

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

QPainterで、ちょっと厄介なtranslateとrotateについてご紹介したいと思います!!

Translate

まず、QPainterのtranslateは、何かを描画したモノを後から移動するものではありません。3DCGをやっているとちょっとややっこしいですよね。(;´∀`)

QPainterは、Widgetの左上が原点(0, 0)になっています。

translateでは、この原点を位置を動かす機能です。ためにし、translateでXとYを100づつ動かしてから四角形を描画してみます!

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.black)
		
		painter.translate(100, 100)
		
		rectangle = QtCore.QRectF(0, 0, 100.0, 100.0)
		painter.drawRect(rectangle)
		
		 
window = PainterSample()
window.setWindowFlags(QtCore.Qt.Window)
window.resize(720, 405)
window.show()

実行してみると、四角形を(0, 0, 100.0, 100.0)で描画してるにも関わらず、原点が動き四角形の描画位置が変わります。

今度は、translateと四角形のコードを逆にしてみます。

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.black)
		
		rectangle = QtCore.QRectF(0, 0, 100.0, 100.0)
		painter.drawRect(rectangle)
		
		painter.translate(100, 100)

window = PainterSample()
window.setWindowFlags(QtCore.Qt.Window)
window.resize(720, 405)
window.show()

原点を動かすっと書きましたが、描画済みのものは動くことはありません(`・ω・´)ゞ

Rotate

rotateもtranslateと同様で、原点の傾きを設定するものです。設定する数値は、度数法(360°とか)です!試しに、rotateを使って、45°傾けてみます。

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.black)
		
		painter.translate(100, 100)
		painter.rotate(45)
		
		rectangle = QtCore.QRectF(0, 0, 100.0, 100.0)
		painter.drawRect(rectangle)

window = PainterSample()
window.setWindowFlags(QtCore.Qt.Window)
window.resize(720, 405)
window.show()

すると四角形が傾いた原点を元に描かれます。

応用

繰り返し処理を使って、ちょっとづつ回転させながら描画させてみます!

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.black)
		
		center = self.rect().center()
		painter.translate(center)
		
		# 描画する回数
		loop = 16
		
		# 一回あたりの回転数
		angle = 360 / loop
		for i in range(loop):
			# rotateの数値は絶対値ではなくて、相対的に動きます。
			painter.rotate(angle)
			
			# 円の描画
			painter.drawEllipse(60, 0, 10, 10)

window = PainterSample()
window.setWindowFlags(QtCore.Qt.Window)
window.resize(720, 405)
window.show()

すると、小さな円が円状に描画されるようになります!オサレなローディング画面が作れそうですね!(*´ω`*)b

仕組みを画像にすると、以下のようになります!赤い玉が、繰り返し処理の最初に描画されるものです!

scaleについては触れることができませんでしたが、同様に原点を元に、描画で指定された座標がスケールされるイメージです!(`・ω・´)ゞ