# AnimationDemoGTK.py (c) Kari Laitinen # http://www.naturalprogramming.com/ # 2006-08-18 File created. # 2009-02-26 Last modification. import gtk from threading import Thread from threading import Event from time import sleep # Note: It is very important inside the loop of the # run() method that the sleep() method is called AFTER # the window contents have been updated. If the sleep() # method is called at the beginning of the loop body, # there will be problems when the program is terminated. # When the animation thread is ordered to stop while it # is sleeping, it tries to update a 'dead window' if the # the value of thread_must_be_stopped is not checked # right after the sleeping period. (I had to work almost # a whole day to find out this.) gtk.gdk.threads_init() # Initializing the gtk's thread engine class AnimationThread ( Thread ) : def __init__( self, given_drawing_area ) : Thread.__init__( self ) self.external_drawing_area = given_drawing_area self.thread_must_be_stopped = Event() print " thread init done " def stop_this_thread( self ) : self.thread_must_be_stopped.set() def run( self ) : while not self.thread_must_be_stopped.isSet() : gtk.gdk.threads_enter() # Acquiring the gtk global mutex self.external_drawing_area.queue_draw() gtk.gdk.threads_leave() # Releasing the gtk global mutex sleep( 1.000 ) # Delay of one second. print " run method ends " class AnimationDemo : def __init__( self ) : self.application_window = gtk.Window( gtk.WINDOW_TOPLEVEL ) self.application_window.set_title( "ANIMATION BY USING A THREAD" ) self.application_window.connect( "destroy", self.exit_this_application ) self.application_window.set_size_request( 600, 500 ) 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.show() self.application_window.show() window_width, window_height = self.application_window.get_size() self.ball_center_point_x = window_width / 2 ; self.ball_center_point_y = window_height / 2 ; self.ball_must_be_shown = False self.animation_thread = AnimationThread( self.drawing_area ) self.animation_thread.start() def drawing_area_exposed( self, area, event ) : if self.ball_must_be_shown == True : graphics_context = \ self.drawing_area.get_style().fg_gc[gtk.STATE_NORMAL] this_drawable = self.drawing_area.window # Note that angles are expressed in 1/64ths of a degree. # 360 degrees is thus represented by value 360*64 this_drawable.draw_arc( graphics_context, True, self.ball_center_point_x - 50, self.ball_center_point_y - 50, 100, 100, 0, 360*64 ) self.ball_must_be_shown = False else : self.ball_must_be_shown = True return True def run( self ) : gtk.main() def exit_this_application( self, widget, data=None ) : self.animation_thread.stop_this_thread() gtk.main_quit() if __name__ == "__main__": this_application = AnimationDemo() this_application.run()