Search code examples
c++gtkgtkmmgtkmm3libsigc++

How to disconnect a signal


I made a program to calculate the area and volume of shapes from a window. Everything works, except one thing regarding the use of Gtk::Entry::signal_activate(). In the following code:

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

 // ...

if I start with option case 2 everything works fine. If I go through case 1 and then case 2, pressing the enter key shifts the focus to the next Gtk::Entry but also launches the calculation() function, which I'm trying to avoid. I think the Gtk::Entry::signal_activate() handler is not disconnected after passing through case 1, but I don't know why since I am calling sigc::connection::disconnect() when entering case 2.

How could I make this work?


Solution

  • First add this header. See documentation from sigc++

    #include <sigc++/connection.h>
    

    We have to disconnect signal and stop it

    Declare in your own class

    sigc::connection c;
    

    then in your main programm we can do something like that

      switch (forme)
      {
      case 1: // carré
        cacheEntry();
        labelForme.set_label(listeDeroulante.get_active_text());
        labelLongueur.set_label("longueur");
        if (c.connected() == false)
        {
          c = elongueur.signal_activate().connect([this]() { calcul(); });
        }
        break;
      case 2: // rectangle
        c.disconnect();//disconnected signal
        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(); elargeur.signal_activate().emission_stop();/*stop signal*/ });
        break;