home *** CD-ROM | disk | FTP | other *** search
/ tusportal.tus.k12.pa.us / tusportal.tus.k12.pa.us.tar / tusportal.tus.k12.pa.us / Wyse / latest-image.raw / 0.img / usr / lib / pygtk / 2.0 / demos / images.py < prev    next >
Text File  |  2010-05-11  |  10KB  |  307 lines

  1. #!/usr/bin/env python
  2. '''Images
  3.  
  4. GtkImage is used to display an image; the image can be in a number of formats.
  5. Typically, you load an image into a GdkPixbuf, then display the pixbuf.
  6. This demo code shows some of the more obscure cases, in the simple case a call
  7. to gtk_image_new_from_file() is all you need.
  8. If you want to put image data in your program as a C variable, use the
  9. make-inline-pixbuf program that comes with GTK+. This way you won't need to
  10. depend on loading external files, your application binary can be self-contained.'''
  11. # pygtk version: Maik Hertha <maik.hertha@berlin.de>
  12.  
  13. import os
  14. import gobject
  15. import gtk
  16.  
  17. IMAGEDIR = os.path.join(os.path.dirname(__file__), 'images')
  18. ALPHA_IMAGE = os.path.join(IMAGEDIR, 'alphatest.png')
  19. GTKLOGO_IMAGE = os.path.join(IMAGEDIR, 'gtk-logo-rgb.gif')
  20. BUDDY_IMAGE = os.path.join(IMAGEDIR, 'floppybuddy.gif')
  21.  
  22. def progressive_prepared_callback(loader, image):
  23.     pixbuf = loader.get_pixbuf()
  24.  
  25.     # Avoid displaying random memory contents, since the pixbuf
  26.     # isn't filled in yet.
  27.     #images.c -> gdk_pixbuf_fill(pixbuf, 0xaaaaaaff)
  28.     pixbuf.fill(0)
  29.     image.set_from_pixbuf(pixbuf)
  30.  
  31.  
  32. def progressive_updated_callback(loader, x, y, width, height, image):
  33.     ''' We know the pixbuf inside the GtkImage has changed, but the image
  34.         itself doesn't know this; so queue a redraw.  If we wanted to be
  35.         really efficient, we could use a drawing area or something
  36.         instead of a GtkImage, so we could control the exact position of
  37.         the pixbuf on the display, then we could queue a draw for only
  38.         the updated area of the image.
  39.     '''
  40.     image.queue_draw()
  41.  
  42. class ImagesDemo(gtk.Window):
  43.     pixbuf_loader = None
  44.     load_timeout = None
  45.     image_stream = None
  46.  
  47.     def __init__(self, parent=None):
  48.         gtk.Window.__init__(self)
  49.         try:
  50.             self.set_screen(parent.get_screen())
  51.         except AttributeError:
  52.             self.connect('destroy', lambda *w: gtk.main_quit())
  53.         self.connect("destroy", self.cleanup_callback)
  54.         self.set_title(self.__class__.__name__)
  55.         self.set_border_width(8)
  56.  
  57.         vbox = gtk.VBox(False, 8)
  58.         vbox.set_border_width(8)
  59.         self.add(vbox)
  60.  
  61.         label = gtk.Label();
  62.         label.set_markup("<u>Image loaded from a file</u>")
  63.         vbox.pack_start(label, False, False, 0)
  64.  
  65.         frame = gtk.Frame()
  66.         frame.set_shadow_type(gtk.SHADOW_IN)
  67.  
  68.         # The alignment keeps the frame from growing when users resize
  69.         # the window
  70.         align = gtk.Alignment(0.5, 0.5, 0, 0)
  71.         align.add(frame)
  72.         vbox.pack_start(align, False, False, 0)
  73.  
  74.         image = gtk.Image()
  75.  
  76.         # use the current directory for the file
  77.         try:
  78.             pixbuf = gtk.gdk.pixbuf_new_from_file(GTKLOGO_IMAGE)
  79.             image.set_from_pixbuf(pixbuf)
  80.  
  81.         except gobject.GError, error:
  82.  
  83.             # This code shows off error handling. You can just use
  84.             # gtk_image_new_from_file() instead if you don't want to report
  85.             # errors to the user. If the file doesn't load when using
  86.             # gtk_image_new_from_file(), a "missing image" icon will
  87.             # be displayed instead.
  88.  
  89.             dialog = gtk.MessageDialog(self,
  90.                 gtk.DIALOG_DESTROY_WITH_PARENT,
  91.                 gtk.MESSAGE_ERROR,
  92.                 gtk.BUTTONS_CLOSE,
  93.                 "Unable to open image file 'gtk-logo-rgb.gif': \n%s" % error)
  94.  
  95.             dialog.connect("response", lambda dlg, resp: dlg.destroy())
  96.             dialog.show()
  97.  
  98.         frame.add(image)
  99.  
  100.         # Animation
  101.  
  102.         label = gtk.Label()
  103.         label.set_markup("<u>Animation loaded from a file</u>")
  104.         vbox.pack_start(label, False, False, 0)
  105.  
  106.         frame = gtk.Frame()
  107.         frame.set_shadow_type(gtk.SHADOW_IN)
  108.  
  109.         # The alignment keeps the frame from growing when users resize
  110.         # the window
  111.  
  112.         align = gtk.Alignment(0.5, 0.5, 0, 0)
  113.         align.add(frame)
  114.         vbox.pack_start(align, False, False, 0)
  115.  
  116.         image = gtk.Image()
  117.         image.set_from_file(BUDDY_IMAGE);
  118.  
  119.         frame.add(image)
  120.  
  121.         # Progressive
  122.  
  123.         label = gtk.Label()
  124.         label.set_markup("<u>Progressive image loading</u>")
  125.         vbox.pack_start(label, False, False, 0)
  126.  
  127.         frame = gtk.Frame()
  128.         frame.set_shadow_type(gtk.SHADOW_IN)
  129.  
  130.         # The alignment keeps the frame from growing when users resize
  131.         # the window
  132.  
  133.         align = gtk.Alignment(0.5, 0.5, 0, 0)
  134.         align.add(frame)
  135.         vbox.pack_start(align, False, False, 0)
  136.  
  137.         # Create an empty image for now; the progressive loader
  138.         # will create the pixbuf and fill it in.
  139.  
  140.         image = gtk.Image()
  141.         image.set_from_pixbuf(None)
  142.         frame.add(image)
  143.  
  144.         self.start_progressive_loading(image)
  145.  
  146.         # Sensitivity control
  147.  
  148.         button = gtk.ToggleButton("_Insensitive");
  149.         vbox.pack_start(button, False, False, 0)
  150.  
  151.         button.connect("toggled", self.on_sensitivity_toggled, vbox)
  152.  
  153.         self.show_all()
  154.  
  155.     def cleanup_callback(self, win):
  156.         if self.load_timeout != 0:
  157.             gtk.timeout_remove(self.load_timeout)
  158.             self.load_timeout = 0
  159.  
  160.         if self.pixbuf_loader is not None:
  161.             self.pixbuf_loader.close()
  162.             self.pixbuf_loader = None
  163.  
  164.         if self.image_stream is not None:
  165.             self.image_stream.close()
  166.             self.image_stream = None
  167.  
  168.  
  169.     def on_sensitivity_toggled(self, togglebutton, container):
  170.         children = container.get_children()
  171.  
  172.         for child in children:
  173.  
  174.             # don't disable our toggle
  175.             if type(child) != type(togglebutton):
  176.                 child.set_sensitive(not togglebutton.get_active())
  177.  
  178.     def start_progressive_loading(self, image):
  179.         ''' This is obviously totally contrived(we slow down loading
  180.             on purpose to show how incremental loading works).
  181.             The real purpose of incremental loading is the case where
  182.             you are reading data from a slow source such as the network.
  183.             The timeout simply simulates a slow data source by inserting
  184.             pauses in the reading process.
  185.         '''
  186.         self.load_timeout = gtk.timeout_add(150, self.progressive_timeout, image)
  187.  
  188.     def progressive_timeout(self, image):
  189.  
  190.         # This shows off fully-paranoid error handling, so looks scary.
  191.         # You could factor out the error handling code into a nice separate
  192.         # function to make things nicer.
  193.  
  194.         if self.image_stream is not None:    # file is already opened
  195.             try:
  196.                 buf = self.image_stream.read(256)
  197.                 bytes_read = len(buf)
  198.  
  199.             except IOError, error:
  200.                 dialog = gtk.MessageDialog(self,
  201.                     gtk.DIALOG_DESTROY_WITH_PARENT,
  202.                     gtk.MESSAGE_ERROR,
  203.                     gtk.BUTTONS_CLOSE,
  204.                     "Failure reading image file 'alphatest.png': %s" % error)
  205.  
  206.                 dialog.connect("response", lambda d, r: d.destroy())
  207.  
  208.                 self.image_stream.close()
  209.                 self.image_stream = None
  210.  
  211.                 dialog.show()
  212.  
  213.                 self.load_timeout = 0
  214.  
  215.                 return False; # uninstall the timeout
  216.  
  217.             if not self.pixbuf_loader.write(buf, bytes_read):
  218.  
  219.                 dialog = gtk.MessageDialog(self,
  220.                            gtk.DIALOG_DESTROY_WITH_PARENT,
  221.                            gtk.MESSAGE_ERROR,
  222.                            gtk.BUTTONS_CLOSE,
  223.                            "Failed to load image")
  224.  
  225.                 dialog.connect("response", lambda d, r: d.destroy())
  226.  
  227.                 self.image_stream.close()
  228.                 self.image_stream = None
  229.  
  230.                 dialog.show()
  231.  
  232.                 self.load_timeout = 0
  233.  
  234.                 return False # uninstall the timeout
  235.  
  236.             #if(feof(image_stream)):
  237.             if bytes_read == 0:
  238.  
  239.                 self.image_stream.close()
  240.                 self.image_stream = None
  241.  
  242.                 # Errors can happen on close, e.g. if the image
  243.                 # file was truncated we'll know on close that
  244.                 # it was incomplete.
  245.  
  246.                 if not self.pixbuf_loader.close():
  247.  
  248.                     dialog = gtk.MessageDialog(self,
  249.                                gtk.DIALOG_DESTROY_WITH_PARENT,
  250.                                gtk.MESSAGE_ERROR,
  251.                                gtk.BUTTONS_CLOSE,
  252.                                "Failed to load image")
  253.  
  254.                     dialog.connect("response", lambda d, r: d.destroy())
  255.                     dialog.show()
  256.  
  257.                     self.pixbuf_loader = None
  258.  
  259.                     self.load_timeout = 0
  260.  
  261.                     return False # uninstall the timeout
  262.  
  263.                 # if feof(image_stream)
  264.                 self.pixbuf_loader = None
  265.  
  266.         else:    # if(image_stream) ...
  267.             try:
  268.                 self.image_stream = open(ALPHA_IMAGE, "rb")
  269.  
  270.             except IOError, error:
  271.                 error_message = "Unable to open image file 'alphatest.png' : %s"
  272.  
  273.                 dialog = gtk.MessageDialog(self,
  274.                     gtk.DIALOG_DESTROY_WITH_PARENT,
  275.                     gtk.MESSAGE_ERROR,
  276.                     gtk.BUTTONS_CLOSE,
  277.                     error_message % error)
  278.  
  279.                 dialog.connect("response", lambda d, r: d.destroy())
  280.                 dialog.show()
  281.  
  282.                 self.load_timeout = 0
  283.  
  284.                 return False # uninstall the timeout
  285.  
  286.             if self.pixbuf_loader is not None:
  287.                 self.pixbuf_loader.close()
  288.                 self.pixbuf_loader = None
  289.  
  290.             self.pixbuf_loader = gtk.gdk.PixbufLoader()
  291.  
  292.             self.pixbuf_loader.connect("area_prepared",
  293.                 progressive_prepared_callback, image)
  294.  
  295.             self.pixbuf_loader.connect("area_updated",
  296.                 progressive_updated_callback, image)
  297.  
  298.         # leave timeout installed
  299.         return True;
  300.  
  301. def main():
  302.     ImagesDemo()
  303.     gtk.main()
  304.  
  305. if __name__ == '__main__':
  306.     main()
  307.