I wrote a small program to replicate your issue:
#include <iostream>
#include <gtkmm.h>
class MyWindow : public Gtk::ApplicationWindow
{
public:
MyWindow()
{
m_btn1.signal_clicked().connect([this](){PerformAction1();});
m_btn2.signal_clicked().connect([this](){PerformAction2();});
m_btn1And2.signal_clicked().connect([this](){PerformActions1And2();});
m_entryA.set_text("Entry A");
m_entryB.set_text("Entry B");
m_layout.attach(m_entryA, 0, 0, 1, 1);
m_layout.attach(m_entryB, 1, 0, 1, 1);
m_layout.attach(m_btn1, 0, 1, 2, 1);
m_layout.attach(m_btn2, 0, 2, 2, 1);
m_layout.attach(m_btn1And2, 0, 3, 2, 1);
add(m_layout);
}
void Calcul()
{
std::cout << "calcul() called" << std::endl;
}
void PerformAction1()
{
// Add another handler here to amplify the problem:
// m_signalEntryA = m_entryA.signal_activate().connect([this](){std::cout << "Action 0 : "; Calcul();});
m_signalEntryA = m_entryA.signal_activate().connect([this](){std::cout << "Action 1 : "; Calcul();});
// Works if you uncomment here:
// m_signalEntryA.disconnect();
}
void PerformAction2()
{
m_signalEntryA = m_entryA.signal_activate().connect([this](){std::cout << "Action 2 : "; Calcul();});
m_signalEntryA.disconnect();
m_signalEntryA = m_entryA.signal_activate().connect([this](){m_entryB.grab_focus();});
m_entryB.signal_activate().connect([this](){Calcul();});
}
void PerformActions1And2()
{
PerformAction1();
PerformAction2();
}
private:
Gtk::Grid m_layout;
Gtk::Entry m_entryA;
Gtk::Entry m_entryB;
Gtk::Button m_btn1{"Action 1"};
Gtk::Button m_btn2{"Action 2"};
Gtk::Button m_btn1And2{"Actions 1 and 2"};
sigc::connection m_signalEntryA;
};
int main(int argc, char* argv[])
{
auto app = Gtk::Application::create(argc, argv, "so.question.q66320704");
MyWindow window;
window.show_all();
return app->run(window);
}
This program has two cases, like yours that do the same fundamental operations on signals. You can activate the different scenarios using the buttons:

Running the program and clicking the buttons, then the Enter key, yields the following output:
- Action 1:
Action 1 : calcul() called
- Action 2: Nothing
- Actions 1 and 2:
Action 1 : calcul() called
From what I can see in this program, it seems that there is some sort of "stacking" in the signal connections. Uncommenting this line:
m_signalEntryA = m_entryA.signal_activate().connect([this](){std::cout << "Action 0 : "; Calcul();});
yield the following output:
Action 0 : calcul() called
Action 1 : calcul() called
This was very surprising as this behavior is not documented in the official documentation. Anyway, to solve your issue, it seems you have to call disconnect early, just before break
.
sigc::connection c = elongueur.signal_activate().connect([this]() { calcul(); });
switch (forme)
{
case 1: //carré
cacheEntry();
c.connected();
labelForme.set_label(listeDeroulante.get_active_text());
labelLongueur.set_label("longueur");
c.disconnect(); // <-- Add this. The connection is no more needed.
break;
case 2: //rectangle
c.disconnect();
elargeur.set_sensitive(true);
labelForme.set_label(listeDeroulante.get_active_text());
labelLongueur.set_label("longueur");
labelLargeur.set_label("largeur");
elongueur.signal_activate().connect([this]() { elargeur.grab_focus(); });
elargeur.signal_activate().connect([this]() { calcul(); });
break;
Note: My Gtkmm version is 3.22.