Question

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 pop-up 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.

Was it helpful?

Solution

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
        }
    }

OTHER TIPS

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

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()

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top