# StarsQt.py Copyright (c) 2010 Kari Laitinen # http://www.naturalprogramming.com # 2010-09-20 File created. # 2011-11-04 Last modification. # This program shows how star shapes can be drawn by using the # QPainterPath class import sys from PyQt4.QtCore import * from PyQt4.QtGui import * class StarShape : def __init__( self, given_star_center_point_x, given_star_center_point_y, given_star_radius = 80, # radius of the bounding circle given_star_color = Qt.yellow, given_hollowness = False ) : self.star_center_point_x = given_star_center_point_x self.star_center_point_y = given_star_center_point_y self.star_radius = given_star_radius self.star_color = given_star_color self.star_is_hollow = given_hollowness def draw( self, painter ) : pass # The following class represents a 5-point star class StarShape5 ( StarShape ) : def draw( self, painter ) : saved_graphics_transform = painter.combinedTransform() painter.translate( self.star_center_point_x, self.star_center_point_y ) # By drawing an arrowhead shape several times and # rotating it by 72 degrees between drawings # it is possible to draw a five-point star. # 5 * 72 = 360 star_5_arrowhead = QPainterPath() # The following coordinates are fixed supposing that the # radius of the star is 80 pixels (points). # Larger or smaller stars are drawn by adjusting the scale of # the coordinate system. If you want to change the default # star radius (80 points), you must modify these coordinates # as well. star_5_arrowhead.moveTo( 0, -80.0 ) # top middle point star_5_arrowhead.lineTo( 47.02, 64.72 ) # to low right point star_5_arrowhead.lineTo( 0, 30.56 ) # to lowish middle point star_5_arrowhead.lineTo( -47.02, 64.72 ) # to low left point star_5_arrowhead.closeSubpath() painter.scale( self.star_radius / 80.0, self.star_radius / 80.0 ) if self.star_is_hollow == True : saved_pen = painter.pen() painter.setPen( QPen( self.star_color, 4 ) ) painter.drawPath( star_5_arrowhead ) painter.rotate( 72 ) # 72 degrees clockwise painter.drawPath( star_5_arrowhead ) painter.rotate( 72 ) # 72 degrees clockwise painter.drawPath( star_5_arrowhead ) painter.setPen( saved_pen ) else : brush_for_filled_star = QBrush( self.star_color ) painter.fillPath( star_5_arrowhead, brush_for_filled_star ) painter.rotate( 72 ) # 72 degrees clockwise painter.fillPath( star_5_arrowhead, brush_for_filled_star ) painter.setTransform( saved_graphics_transform ) # The following class represents a 6-point star class StarShape6 ( StarShape ) : def draw( self, painter ) : saved_graphics_transform = painter.combinedTransform() painter.translate( self.star_center_point_x, self.star_center_point_y ) star_6_triangle = QPainterPath() # A six-point star will be drawn by drawing two triangles, so # that the coordinate system is rotated 180 degrees between drawings. # The following coordinates are fixed supposing that the # radius of the star is 80 pixels (points). # Larger or smaller stars are drawn by adjusting the scale of # the coordinate system. If you want to change the default # star radius (80 points), you must modify these coordinates # as well. star_6_triangle.moveTo( 0, -80.0 ) # start from the top point star_6_triangle.lineTo( 69.28, 40.0 ) # to lower right point star_6_triangle.lineTo( -69.28, 40.0 ) # to lower left point star_6_triangle.closeSubpath() ; # back to top point painter.scale( self.star_radius / 80.0, self.star_radius / 80.0 ) if self.star_is_hollow == True : saved_pen = painter.pen() painter.setPen( QPen( self.star_color, 4 ) ) painter.drawPath( star_6_triangle ) painter.rotate( 180 ) # 180 degrees clockwise painter.drawPath( star_6_triangle ) painter.setPen( saved_pen ) else : brush_for_filled_star = QBrush( self.star_color ) painter.fillPath( star_6_triangle, brush_for_filled_star ) painter.rotate( 180 ) ; # 180 degrees clockwise painter.fillPath( star_6_triangle, brush_for_filled_star ) painter.setTransform( saved_graphics_transform ) class StarsWindow ( QWidget ) : def __init__( self, parent=None ) : QWidget.__init__( self, parent ) self.setGeometry( 100, 100, 850, 600 ) self.setWindowTitle( "DEMONSTRATING 2D GRAPHICS OPERATIONS" ) # Some of the stars defined below have the same position on the screen. # For example, both the large pink star and the small red star # have their center point at (300,300). The small red star is thus # drawn inside the larger pink star. self.default_star_5 = StarShape5( 100, 300 ) self.large_pink_star_5 = StarShape5( 300, 300, 120, QColor( "pink" ), False ) self.small_red_star_5 = StarShape5( 300, 300, 50, Qt.red, False ) self.hollow_star_5 = StarShape5( 500, 300, 60, Qt.white, True ) self.larger_star_6 = StarShape6( 700, 300, 100, Qt.magenta, False ) self.smaller_star_6 = StarShape6( 700, 300, 60, Qt.black, True ) def paintEvent( self, event ) : painter = QPainter() painter.begin( self ) painter.fillRect( 0, 0, self.width(), self.height(), Qt.darkGray ) self.default_star_5.draw( painter ) self.large_pink_star_5.draw( painter ) self.small_red_star_5.draw( painter ) self.hollow_star_5.draw( painter ) self.larger_star_6.draw( painter ) self.smaller_star_6.draw( painter ) painter.end() # Here is the "main" program: def main( args ) : this_application = QApplication( args ) application_window = StarsWindow() application_window.show() this_application.exec_() if __name__== "__main__" : main( sys.argv ) # NOTES: # The following triangle could be used to draw a five-point star. # With this triangle we would not need to rotate the coordinate system. # star_5_triangle = QPainterPath() # star_5_triangle.moveTo( -76.08, -24.72 ) # upper left point # star_5_triangle.lineTo( 76.08, -24.72 ) # to upper right point # star_5_triangle.lineTo( 0, 30.56 ) # to middle low point # star_5_triangle.closeSubpath() # The following shape is in use in the corresponding Java program. # It did not work properly in Qt. # star_shape_5 = QPainterPath() # star_shape_5.moveTo( 76.08, -24.72 ) # start from upper right point # star_shape_5.lineTo( -47.02, 64.72 ) # to lower left point # star_shape_5.lineTo( 0, -80.0 ) # to upper middle point # star_shape_5.lineTo( 47.02, 64.72 ) # to lower right point # star_shape_5.lineTo( -76.08, -24.72 ) # to upper left point # star_shape_5.closeSubpath() # to upper right point