# DrawingLinesGTK.py (c) Kari Laitinen # http://www.naturalprogramming.com # The development of this program has been sponsored by Nokia Multimedia. # 2006-08-30 File created. # 2009-02-11 Last modification. # This program works in the same way as DrawingLinesApplet.java. import gtk class DrawingLinesApplication : def __init__( self ) : self.application_window = gtk.Window( gtk.WINDOW_TOPLEVEL ) self.application_window.set_title( "DRAWING LINES WITH THE MOUSE" ) self.application_window.connect( "destroy", self.exit_this_application ) self.application_window.set_size_request( 600, 400 ) self.drawing_area = gtk.DrawingArea() self.application_window.add( self.drawing_area ) self.drawing_area.connect( "expose-event", self.drawing_area_exposed ) self.drawing_area.connect( "button_press_event", self.mouse_button_pressed ) self.drawing_area.connect( "motion_notify_event", self.mouse_motion_notified ) self.drawing_area.connect( "button_release_event", self.mouse_button_released ) self.drawing_area.set_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.BUTTON_RELEASE_MASK ) self.drawing_area.show() self.application_window.show() self.window_width, self.window_height = \ self.application_window.get_size() self.list_of_starting_points = [] self.list_of_ending_points = [] self.line_is_being_drawn = False def mouse_button_pressed( self, widget, event ) : self.start_of_new_line = ( int( event.x ), int( event.y ) ) self.line_is_being_drawn = True # The following method processes the many events that are # generated when the mouse (or pointer) is being moved. # Mostly the system generates only hints about pointer # movements. (This is achieved by specifying # POINTER_MOTION_HINT_MASK in the set_events() call.) # As I understand it, a new hint will be generated only after # the previous hint is processed and get_pointer() method # is called. # The "state" that is mentioned in this method provides # information related to which mouse button is in use. # This information is not, however, exploited. def mouse_motion_notified( self, widget, event ) : if event.is_hint : pointer_position_x, pointer_position_y, state = \ event.window.get_pointer() else : # It seems that this else block is never entered. print "A non-hint motion event" pointer_position_x = event.x pointer_position_y = event.y state = event.state self.end_of_new_line = ( int( pointer_position_x ), int( pointer_position_y ) ) self.drawing_area.queue_draw() return True def mouse_button_released( self, widget, event ) : self.end_of_new_line = ( int( event.x ), int( event.y ) ) self.list_of_starting_points.append( self.start_of_new_line ) self.list_of_ending_points.append( self.end_of_new_line ) self.line_is_being_drawn = False self.drawing_area.queue_draw() return True def drawing_area_exposed( self, area, event ) : graphics_context = \ self.drawing_area.get_style().fg_gc[gtk.STATE_NORMAL] this_drawable = self.drawing_area.window graphics_context.foreground = \ this_drawable.get_colormap().alloc_color( "black" ) for line_index in range( len( self.list_of_starting_points ) ) : # The coordinates of a point are stored as a tuple ( x, y ) # When this kind of a tuple is being indexed, 0 refers to # x coordinate and 1 refers to y coordinate of a point this_drawable.draw_line( graphics_context, self.list_of_starting_points[ line_index ][ 0 ], self.list_of_starting_points[ line_index ][ 1 ], self.list_of_ending_points[ line_index ][ 0 ], self.list_of_ending_points[ line_index ][ 1 ] ) if self.line_is_being_drawn == True : # A line that is not yet complete is drawn with red color graphics_context.foreground = \ this_drawable.get_colormap().alloc_color( "red" ) this_drawable.draw_line( graphics_context, self.start_of_new_line[ 0 ], self.start_of_new_line[ 1 ], self.end_of_new_line[ 0 ], self.end_of_new_line[ 1 ] ) return True def run( self ) : gtk.main() def exit_this_application( self, widget, data=None ) : gtk.main_quit() if __name__ == "__main__": this_application = DrawingLinesApplication() this_application.run()