信号从 gtkmm 弹出列表中触发两次

Posted

技术标签:

【中文标题】信号从 gtkmm 弹出列表中触发两次【英文标题】:Signal fires twice from gtkmm popup list 【发布时间】: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 会被调用两次。当点击已经选中的单选按钮时,它只会被调用一次。

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

【问题讨论】:

【参考方案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】:

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

【讨论】:

以上是关于信号从 gtkmm 弹出列表中触发两次的主要内容,如果未能解决你的问题,请参考以下文章

gtkmm4:在 Gtk::HeaderBar 中时,Gtk::Button 点击​​信号不会触发

这段代码有啥错误

gtkmm & glade - 多个窗口不工作

QT中QLineEdit的editingFinished()信号在按下回车时会触发两次的解决办法

附件提醒后 OnSend 触发两次

从可重用单元中出列时,自定义 CollectionViewCell 上会触发啥方法?