Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Destroying signal slot connections correctly
Qt 6.11 is out! See what's new in the release blog

Destroying signal slot connections correctly

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 3 Posters 1.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Suli Sahne
    wrote on last edited by
    #1

    Hello, I have a question about the destruction of signal-slot connections.

    A signal-slot connection is automatically destroyed when either the sender or receiver instance is destroyed. However, when replacing the sender or receiver pointer, the instance itself is usually not destroyed; you simply overwrite the pointer (except in the case of unique_ptr or shared_ptr with a reference count of 0).

    For example, the MyClass::saved signal remains connected to every Foo instance that was ever set, even if MyClass now contains a completely different Foo pointer.

    void MyClass::setter(Foo* foo)
    {
        m_foo = foo;
        QObject::connect(m_foo, &Foo::saved, this, &MyClass::saved);
    }
    

    To ensure that MyClass::saved is only triggered by the current m_foo member, you need to do the following:

    void MyClass::setter(Foo* foo)
    {
        if (m_foo == foo)
            return;
        
        if (m_foo)
            // Disconnect all signals from the old m_foo connected to this
            m_foo.disconnect(this);
        
        m_foo = foo;
        
        if (m_foo)
            QObject::connect(m_foo, &Foo::saved, this, &MyClass::saved);    
    }
    

    This approach seems cumbersome and prone to errors. My question is: Is my implementation correct, have I misunderstood something, or is there an easier way?

    JonBJ 1 Reply Last reply
    0
    • A Offline
      A Offline
      Asperamanca
      wrote on last edited by
      #2

      connect returns a QMetaObject::Connection
      You can pass that as a parameter of QObject::disconnect
      So you could write your own class that keeps track of certain connections, and disconnects them on demand.

      1 Reply Last reply
      2
      • S Suli Sahne

        Hello, I have a question about the destruction of signal-slot connections.

        A signal-slot connection is automatically destroyed when either the sender or receiver instance is destroyed. However, when replacing the sender or receiver pointer, the instance itself is usually not destroyed; you simply overwrite the pointer (except in the case of unique_ptr or shared_ptr with a reference count of 0).

        For example, the MyClass::saved signal remains connected to every Foo instance that was ever set, even if MyClass now contains a completely different Foo pointer.

        void MyClass::setter(Foo* foo)
        {
            m_foo = foo;
            QObject::connect(m_foo, &Foo::saved, this, &MyClass::saved);
        }
        

        To ensure that MyClass::saved is only triggered by the current m_foo member, you need to do the following:

        void MyClass::setter(Foo* foo)
        {
            if (m_foo == foo)
                return;
            
            if (m_foo)
                // Disconnect all signals from the old m_foo connected to this
                m_foo.disconnect(this);
            
            m_foo = foo;
            
            if (m_foo)
                QObject::connect(m_foo, &Foo::saved, this, &MyClass::saved);    
        }
        

        This approach seems cumbersome and prone to errors. My question is: Is my implementation correct, have I misunderstood something, or is there an easier way?

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #3

        @Suli-Sahne
        As @Asperamanca says. However, that relies on you correctly noting which/all connections. If you no longer what anything connected to old m_foo, whatever/wherever that might be, then consider m_foo->disconnect() or disconnect(m_foo, nullptr, nullptr, nullptr). Further details at https://doc.qt.io/qt-6/qobject.html#disconnect.

        1 Reply Last reply
        1
        • S Offline
          S Offline
          Suli Sahne
          wrote on last edited by
          #4

          @Asperamanca, @JonB
          Thank you for your suggestion. I am aware of the various methods to disconnect a connection. My main concern was the complexity of the code, and I was hoping there might be a simpler solution, as I assume others might have faced this issue as well.

          1 Reply Last reply
          0
          • S Offline
            S Offline
            Suli Sahne
            wrote on last edited by
            #5

            I have created a class that ensures only one connection is active at a time. I would like to post the code, unfortunately akismet.com thinks it would be spam..
            In any case, thank you very much for your help.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved