信号从 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 点击信号不会触发