views:

362

answers:

4

It's been a while since I used GTK+, and the last time I did was in C, not using gtkmm and C++ as I am now. Anyway, I have what I think should be an easy problem to solve:

I have a popup menu consisting of a list of radio buttons, and when I click one of them I want some action to occur. The code goes like this:

    Gtk::RadioMenuItem::Group group;
    for ( size_t i = 1; i < LH_MAX; ++i )
    {
        Gtk::RadioMenuItem* pItem = new Gtk::RadioMenuItem( group, names[i], names[i] );
        pItem->set_name( names[i] );
        pItem->signal_activate().connect( sigc::mem_fun(*this, &MyClass::on_item_activated) );
        pItem->show();
        m_Menu.append( *Gtk::manage(pItem) );
    }

The only problem I see is that MyClass::on_item_activated gets called twice when a previously-unselected radio button is chosen from the menu. It's called only once when the already-selected radio button is clicked.

I'm guessing that the first firing is to say "something is no longer activate," and the second is for the new radio button activation. Whether I'm right or wrong, the question is the same: how best can I have my handler only take action once per click? Either I need the handler to get called only once, or I need something to check from inside it to know if the callback is a "duplicate" or not.

A: 

I don't know exactly what you're trying to accomplish (or what MyClass is and what base classes it inherits from), but connecting to signal_toggled() might be more useful than signal_activate()

jonner
`MyClass` inherits from nothing (for the purposes of this discussion at least). Its `on_item_activated` method is meant to open a popup window (hence calling it twice is bad). I'll try `signal_toggled()` when I get back to this.
John Zwinck
+1  A: 

You could use sigc::bind to supply the item as a argument to the callback function.

pItem->signal_activate().sigc::bind(sigc::mem_fun(*this,&MyClass::on_item_activated),pItem));

Then you can use item->get_active() in the callback to respond to activations only.

      void MyClass::on_item_activated(Gtk::RadioMenuItem* item) {
        if (item->get_active()) {
               // Do some stuff
        }
    }
Haven't tried it yet but this sounds like the best approach.
John Zwinck
A: 

/Agree with Johannes. Check if the item is activated when receiving the signal.

PoweRoy
+1  A: 

That's what I do too, connect to signal_toggled() and check if get_active() is true.

Soo Wei Tan