Сигнал срабатывает дважды из всплывающего списка gtkmm - PullRequest
0 голосов
/ 07 января 2009

Прошло много времени с тех пор, как я использовал GTK +, и последний раз, когда я делал это, был в C, не используя gtkmm и C ++, как сейчас. Во всяком случае, у меня есть то, что я думаю, должно быть легко решить проблему:

У меня есть всплывающее меню, состоящее из списка переключателей, и когда я нажимаю на одну из них, я хочу, чтобы какое-то действие произошло. Код выглядит так:

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

Единственная проблема, которую я вижу, состоит в том, что MyClass::on_item_activated вызывается дважды, когда в меню выбран ранее не выбранный переключатель. Он вызывается только один раз, когда нажата уже выбранная радиокнопка.

Я предполагаю, что первое срабатывание состоит в том, чтобы сказать «что-то больше не активируется», а второе - для активации новой радиокнопки. Прав ли я или нет, вопрос один и тот же: как лучше, чтобы мой обработчик действовал только один раз за клик? Либо мне нужен обработчик для вызова только один раз, либо мне нужно что-то проверить изнутри, чтобы узнать, является ли обратный вызов «дубликатом» или нет.

Ответы [ 4 ]

1 голос
/ 14 марта 2009

Я тоже так делаю, подключаюсь к signal_toggled() и проверяю, истинно ли get_active().

1 голос
/ 13 января 2009

Вы можете использовать sigc :: bind для предоставления элемента в качестве аргумента функции обратного вызова.

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

Тогда вы можете использовать item-> get_active () в обратном вызове, чтобы отвечать только на активации.

      void MyClass::on_item_activated(Gtk::RadioMenuItem* item) {
        if (item->get_active()) {
               // Do some stuff
        }
    }
0 голосов
/ 13 января 2009

/ Согласен с Йоханнесом. Проверьте, активирован ли пункт при получении сигнала.

0 голосов
/ 10 января 2009

Я не знаю точно, что вы пытаетесь достичь (или что такое MyClass и какие базовые классы он наследует), но подключение к signal_toggled() может быть более полезным, чем signal_activate()

...