2009-01-06 6 views
0

Cela fait un moment que j'ai utilisé GTK +, et la dernière fois que je l'ai fait était en C, n'utilisant pas gtkmm et C++ comme je le suis maintenant. Quoi qu'il en soit, j'ai ce que je pense devrait être un problème facile à résoudre:Le signal se déclenche deux fois depuis la liste déroulante gtkmm

J'ai un menu contextuel consistant en une liste de boutons radio, et quand je clique sur l'un d'entre eux je veux que quelque chose se produise. Le code va comme ceci:

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

Le seul problème que je vois est que MyClass::on_item_activated est appelé deux fois quand un bouton radio précédemment désélectionné est choisi dans le menu. Il est appelé une seule fois lorsque le bouton radio déjà sélectionné est cliqué.

Je suppose que le premier tir est de dire "quelque chose n'est plus activé", et le second est pour le nouveau bouton d'activation radio. Que je me trompe ou que je me trompe, la question est la même: comment puis-je faire en sorte que mon gestionnaire n'agisse qu'une fois par clic? Soit j'ai besoin du gestionnaire pour être appelé une seule fois, soit j'ai besoin de quelque chose pour vérifier de l'intérieur pour savoir si le rappel est un "doublon" ou non.

Répondre

1

Vous pouvez utiliser sigc: : bind pour fournir l'élément en tant qu'argument à la fonction de rappel. Ensuite, vous pouvez utiliser item-> get_active() dans le rappel pour répondre aux activations uniquement.

 void MyClass::on_item_activated(Gtk::RadioMenuItem* item) { 
     if (item->get_active()) { 
       // Do some stuff 
     } 
    } 
+0

N'a pas encore essayé mais cela semble être la meilleure approche. –

+0

Mais comment pouvez-vous garantir que pItem sera toujours valide au moment de ce rappel? J'ai essayé cette approche et mon application s'est écrasée. pItem a été retourné à partir d'un objet Builder Glade ... –

0

Je ne sais pas exactement ce que vous essayez d'accomplir (ou ce que MyClass est et ce que les classes de base qu'il hérite de), mais la connexion à signal_toggled() pourrait être plus utile que signal_activate()

+0

'MyClass' hérite de rien (pour les besoins de cette discussion au moins). Sa méthode 'on_item_activated' est destinée à ouvrir une fenêtre contextuelle (l'appeler deux fois est donc mauvais). Je vais essayer 'signal_toggled()' quand j'y reviendrai. –

0

/D'accord avec Johannes. Vérifiez si l'élément est activé lors de la réception du signal.

1

C'est ce que je fais aussi, connectez-vous à signal_toggled() et vérifiez si get_active() est vrai.

Questions connexes