[pygtk] Re: Creating a gtk.MenuToggleToolButton

Richard Procter rnp at paradise.net.nz
Thu Nov 15 05:50:04 WST 2007


On 14/11/2007, at 2:46 PM, Richard Procter wrote:

> Hi All,
>
> I need a gtk.MenuToolButton that contains a gtk.ToggleButton,
> not a gtk.Button.
>
> Has anyone managed to create such a beast purely in python?

This does this trick, but it's a hack. Better would be to reimplement
gtk.MenuToolButton by subclassing gtk.ToolItem. Even better
would be to parameterise gtk.ToolButton to use a given button widget,
but I don't have time to wade through the C.

regards,
Richard

class MenuToolToggleButton(gtk.MenuToolButton):
     """ This hack provides a MenuToolButton that toggles, without
     having to code our own replacement or touch GTK itself. It fondles
     the MenuToolButton's innards, so YMMV. """

     assert gtk.gtk_version == (2,8,17) # known to run

     __gsignals__ = {
         'toggled': (gobject.SIGNAL_RUN_LAST,
                     gobject.TYPE_NONE,
                     ())
         }

     def _reconfiguring(self, dummy):
         """ Our proxy_button would be destroyed if we didn't whisk it
         to saftey here, before the gtk.MenuToolButton explicitly  
destroys its
         parent """

         parent = self.proxy_button.get_parent()
         if parent: parent.remove(self.proxy_button)

     def _reconfigured(self, dummy):
         """ The MenuToolButton has configured its button; snaffle  
this for ours """

         def copy_button_properties(dest, src):
             assert isinstance(src, gtk.Button)
             assert isinstance(dest, src.__class__)

             props = [p for p in gobject.list_properties(src)

                      if (p.flags & gobject.PARAM_WRITABLE and
                          p.flags & gobject.PARAM_READABLE and
                          p.owner_type == gtk.Button.__gtype__)]

             for prop in props:
                 dest.set_property(prop.name, src.get_property 
(prop.name))

         def adopt_child(dest, src):
             if dest.get_child():
                 dest.remove(dest.get_child())

             child = src.get_child()

             if child:
                 src.remove(child)
                 dest.add(child)

         copy_button_properties(self.proxy_button, self.subject_button)
         adopt_child(self.proxy_button, self.subject_button)

         if self.proxy_button.get_parent() is None:
             self.get_child().add(self.proxy_button)

     def _on_proxy_click(self, proxy, *args): self.emit('clicked',  
*args)
     def _on_proxy_toggled(self, proxy, *args): self.emit('toggled',  
*args)

     def __init__(self, stock_id):
         gtk.MenuToolButton.__init__(self, stock_id=stock_id)
         box = self.get_child()

         self.subject_button = box.get_children()[0] # keep it alive
         box.remove(self.subject_button)

         self.proxy_button = gtk.ToggleButton()
         self.proxy_button.show_all()
         self.proxy_button.connect('clicked', self._on_proxy_click)
         self.proxy_button.connect('toggled', self._on_proxy_toggled)

         self.connect('toolbar-reconfigured', self._reconfiguring)
         self.connect_after('toolbar-reconfigured', self._reconfigured)

gobject.type_register(MenuToolToggleButton)






More information about the pygtk mailing list