# PictureShowGTK.py (c) Kari Laitinen # http://www.naturalprogramming.com/ # 2006-11-23 File created. # 2009-02-25 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_main_thread_object ) : Thread.__init__( self ) self.main_thread_object = given_main_thread_object 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.main_thread_object.change_picture_and_redraw() gtk.gdk.threads_leave() # Releasing the gtk global mutex sleep( 3.000 ) # Delay of three seconds. print " run method ends " class PictureShow : def __init__( self ) : self.application_window = gtk.Window( gtk.WINDOW_TOPLEVEL ) self.application_window.set_title( "SHOWING A SEQUENCE OF PICTURES" ) self.application_window.connect( "destroy", self.exit_this_application ) self.application_window.set_size_request( 800, 600 ) 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() picture_file_names = ( "yellow_field_by_vincent_van_gogh.jpg", "night_watch_by_rembrandt.jpg", "persistence_of_memory_by_dali.jpg", "demoiselles_de_avignon_by_picasso.jpg", "mona_lisa_by_leonardo.jpg" ) self.pictures_to_be_shown = [] for file_name in picture_file_names : picture_as_pixel_buffer = gtk.gdk.pixbuf_new_from_file( file_name ) self.pictures_to_be_shown.append( picture_as_pixel_buffer ) self.index_of_current_picture = 0 self.animation_thread = AnimationThread( self ) self.animation_thread.start() def change_picture_and_redraw( self ) : self.index_of_current_picture += 1 if self.index_of_current_picture >= len( self.pictures_to_be_shown ) : self.index_of_current_picture = 0 self.drawing_area.queue_draw() 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 this_drawable.draw_pixbuf( graphics_context, self.pictures_to_be_shown[ self.index_of_current_picture ], 0, 0, 30, 20 ) 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 = PictureShow() this_application.run()