[pygtk] "deactivate" signal emitted twice, args corrupted

Karl Ostmo kostmo at gmail.com
Sun Sep 7 05:31:53 WST 2008


This is a follow up to my last mail, with the subject "emulate Live
Bookmarks buttons?"

I've made some progress in creating this "Menu Button" widget, but have met
some hangups.  The Live Bookmarks buttons I was referring to previously, by
the way, are XUL entities described here:
http://developer.mozilla.org/en/XUL/PopupGuide/MenuButtons#The_%27menu%27_button

In PyGTK I have connected a popup menu to a Toggle Button.  When the popup
menu disappears, I would like the Toggle Button to bounce back to an
"un-pressed" state.  To accomplish this, I connect a callback to the
"deactivate" signal of the menu, passing a reference to the button, and then
call button.set_active(False).  This works OK, except for the fact that the
"deactivate" signal gets emitted twice.

I normally wouldn't mind this peculiarity, since calling set_active(False) a
second time has no additional effect.  However, a warning arises if I
trigger "activate" callbacks from the MenuItem's.  Upon the second emssion
of the "deactivate" signal, its callback produces this:

./menu_toolbutton.py:53: GtkWarning: gtk_toggle_tool_button_set_active:
assertion `GTK_IS_TOGGLE_TOOL_BUTTON (button)' failed
  button.set_active(False)

Upon further investigation, the reference to "button" prints out as this:
button = <gtk.ToggleToolButton object at 0x826fcd4 (uninitialized at 0x0)>

I have found that the "button" argument gets corrupted in this way when I do
significant "work" (such as importing opencv) in the "activate" callback.
I've posted code that produces this effect below.  Please let me know if you
can reproduce this, and any workarounds you can think of.

Karl


#!/usr/bin/python

from pygtk import require
require('2.0')
import gtk

class Playground(gtk.Window):
    def __init__(self):
        gtk.Window.__init__( self, gtk.WINDOW_TOPLEVEL )
        vbox = gtk.VBox(False)
        self.add(vbox)
        vbox.set_size_request(100, -1)
        toolbar = gtk.Toolbar()
        toolbutton = gtk.ToolButton()

        toggle_button = gtk.ToggleToolButton(gtk.STOCK_ADD)
        toolbar.insert(toggle_button, -1)

        menu = gtk.Menu()
        video_source_options = ["Milk", "Cookies"]
        [menu.append(gtk.MenuItem(video_source)) for video_source in
video_source_options]
        for i, child in enumerate(menu.get_children()):
            child.connect("activate", self.cb_menu_activate,
video_source_options[i])
        menu.show_all()
        toggle_button.connect( "clicked", self.popup_cb, menu )
        menu.connect( "deactivate", self.deactivate_cb, toggle_button )

        vbox.pack_start(toolbar, False, False)
        self.show_all()

    def cb_menu_activate(self, menu, child_index):

        import opencv
#        import cairo
        print "Activated item", child_index

    def deactivate_cb(self, menu, button):
        print "Button object:", button
        button.set_active(False)

    def popup_cb(self, widget, menu):
        menu.popup(None, None, None, 1, 0)

if __name__ == "__main__":
    application = Playground()
    gtk.main()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.daa.com.au/pipermail/pygtk/attachments/20080906/79917ea6/attachment.htm 


More information about the pygtk mailing list