Python qt: qpainter

From wikinotes

Basics

  • QPainter objects can paint on to widgets or pixmaps
  • 'brush' classes like QPen or fillRect are what you paint with
  • If painting to a pixmap, you can paint anywhere
  • If painting to a widget, it must be from a function is connected to a paint event OR in self.paintEvent( self, event) which runs when object is creted.
  • QPainter objects rendered to widgets can be zoomed

QWidget

class PaintedObj( QtGui.QWidget ):
	def __init__(self):
		super( PaintedObj, self ).__init__()

	def paintEvent(self,event):
		painter = QtGui.QPainter()

		painter.begin( pixmap )
		painter.fillRect( 0,0, 100,100, '#222222' )
		painter.end()

QPixmap

		## Widgets
		layout  = QtGui.QVBoxLayout()
		qlabel  = QtGui.QLabel()
		painter = QtGui.QPainter()


		## Contents
		pixmap = QtGui.QPixmap( 300, 300 )   ## Before Painting, pixmaps MUST have a size

		painter.begin( pixmap )
		painter.setPen( '#FF0000' )
		painter.fillRect( 0,0, pixmap.width(), pixmap.height(), '#222222' )  ## set background colour
		painter.drawRect( 10,10, 100, 100 )                                  ## draw a bounding box using pen
		painter.end()

		qlabel.setPixmap( pixmap )


		## Positions
		self.setLayout( layout )	
		layout.addWidget( qlabel )



Interactive Bounding Box

class DrawBoundingBox( newUI.NewWindow ):
	def main(self):
		"""
		Simple QLabel widget, whose pixmap gets updated
		with a bounding box as the user clicks.
		"""

		## Widgets
		layout = QtGui.QVBoxLayout()

		self.qlabel  = QtGui.QLabel()
		painter = QtGui.QPainter()


		## Contents
		self.pixmap = QtGui.QPixmap( 300, 300 )

		painter.begin( self.pixmap )
		painter.setPen( '#FF0000' )
		painter.fillRect( 0,0, self.pixmap.width(), self.pixmap.height(), '#222222' )
		painter.drawRect( 10,10, 100, 100 )
		painter.end()

		self.qlabel.setPixmap( self.pixmap )


		## Positions
		self.setLayout( layout )	
		layout.addWidget( self.qlabel )


	def mousePressEvent( self, event ):
		"""
		Record position at time that the mouse was pressed.
		"""
		self.startpos    = event.pos()				## position in relation to widget (accurate first event)
		self.startglobal = event.globalPos()		## global screen position (at time of event, required for accuracy)


	def mouseMoveEvent( self, event ):
		"""
		Draw Bounding box ( in relation to start-position )
		"""

		## measure the difference relative to startpoint
		pos = event.globalPos()

		x = pos.x() - self.startglobal.x()
		y = pos.y() - self.startglobal.y()


		painter = QtGui.QPainter()
		painter.begin( self.pixmap )
		painter.setPen('#00FF00')

		## clear background
		painter.fillRect( 0,0, self.pixmap.width(), self.pixmap.height(), '#222222' )

		## draw rect
		painter.drawRect( self.startpos.x(), self.startpos.y(), x, y )	## this stores the x,y, then the difference relative to x,y
		painter.end()

		self.qlabel.setPixmap( self.pixmap )

Bar Graphs

Qt does not provide any specific widget for creating bar graphs, but the QPainter tools are more than sufficient to cover just about anything you could want.


painter = QPainter()
painter.begin(pixmap)


## flat bg colour
painter.fillRect( 0,0,  pixmap.width(), pixmap.height(), '#222222' )

## graph line A
painter.setPen( QPen(Qt.red, 20) )
painter.drawLine( 0,30, 100,30 )

## graph line B
painter.setPen( QPen(Qt.red, 20) )
painter.drawLine( 0,60, 100,60 )

painter.end()

Polygons

Creates, paints a triangle. Then uses a QtGui.QMatrix to rotate it.


        triangle = QtGui.QPolygon()
        triangle.append( QtCore.QPoint(0 , 0 ) )
        triangle.append( QtCore.QPoint(30, 0 ) )
        triangle.append( QtCore.QPoint(0 , 30) )
        print( triangle.toList() )

        matrix = QtGui.QMatrix()
        matrix.rotate(90)
        matrix.translate(0, -30)
        triangle2 = matrix.map(triangle)
        print( triangle2.toList() )