【问题标题】:Signal fires twice from gtkmm popup list信号从 gtkmm 弹出列表中触发两次
【发布时间】:2009-01-06 23:21:17
【问题描述】:

自从我使用 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 会被调用两次。当点击已经选中的单选按钮时,它只会被调用一次。

我猜第一次触发是说“某些东西不再激活”,第二次触发是为了激活新的单选按钮。不管我是对是错,问题都是一样的:我怎样才能让我的处理程序每​​次点击只采取一次行动?要么我需要处理程序只被调用一次,要么我需要从它内部检查以了解回调是否是“重复的”。

【问题讨论】:

    标签: gtk signals gtkmm


    【解决方案1】:

    您可以使用 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
            }
        }
    

    【讨论】:

    • 但是如何保证 pItem 在回调发生时仍然有效?我尝试了这种方法,但我的应用程序崩溃了。 pItem 是从 Glade 构建器对象返回的...
    【解决方案2】:

    我也是这样做的,连接到signal_toggled() 并检查get_active() 是否为真。

    【讨论】:

      【解决方案3】:

      我不确切知道您要完成什么(或 MyClass 是什么以及它继承自什么基类),但连接到 signal_toggled() 可能比 signal_activate() 更有用

      【讨论】:

      • MyClass 从无继承(至少为了本次讨论的目的)。它的on_item_activated 方法旨在打开一个弹出窗口(因此调用它两次是不好的)。当我回到这个问题时,我会尝试signal_toggled()
      【解决方案4】:

      /同意约翰内斯的观点。收到信号时检查物品是否被激活。

      【讨论】:

        猜你喜欢
        • 2018-03-24
        • 1970-01-01
        • 1970-01-01
        • 2015-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-25
        相关资源
        最近更新 更多