Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
qtws26_logo

The Qt Event of the Year: Qt World Summit 2026

Save Your Spot >
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Destroy the signal/slot connection when the slot receives the signal
Qt 6.12 LTS is out! See what's new in the release blog

Destroy the signal/slot connection when the slot receives the signal

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 6 Posters 3.5k Views
  • 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.
  • J johnyang

    Is there a way to destroy the signal/slot connection once the signal has been triggered so this connection only gets triggered once? I came across the following code:
    std::unique_ptr<QObject> context{ new QObject };
    QObject* pcontext = context.get();
    auto connection =
    connect(this,
    &SenderClass::send,
    pcontext,
    this, context = std::move(context) mutable
    {
    context.reset();
    // do something when received the signal
    });

    When context is reset, the connection is destroyed. Is this a bad practice? It seems to be working alright but some developer thinks it is dangerous because pcontext owns that lambda function which destroys itself.

    or is there another way to achieve the same behaviour?

    J.HilkJ Offline
    J.HilkJ Offline
    J.Hilk
    Moderators
    wrote on last edited by
    #3

    @johnyang I don't really see the reason why you would want a single shot connection?

    Why don't you simply call the function directly?

    That said, @jsulm is correct, calling disconnect is probably the correct approach. However it can be tricky and I would suggest using QMetaObject::Connection explicitly

    QMetaObject::Connection conn;
    conn = QObject::connect(sender, &Sender::signal, [=]() mutable {
        // Slot code to be executed
        // ...
    
        // Disconnect the connection
        QObject::disconnect(conn);
    });
    

    at least you don't end up with unnecessary object creations/allocations


    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


    Q: What's that?
    A: It's blue light.
    Q: What does it do?
    A: It turns blue.

    J 1 Reply Last reply
    2
    • jsulmJ jsulm

      @johnyang Please format your code properly.
      You can simply call disconnect() (https://doc.qt.io/qt-6/qobject.html#disconnect).

      J Offline
      J Offline
      johnyang
      wrote on last edited by
      #4

      @jsulm Somehow it won't let me post code with this error "Post content was flagged as spam by Akismet.com". However I was using QT5. But that seems to point me to the right direction.

      1 Reply Last reply
      0
      • J.HilkJ J.Hilk

        @johnyang I don't really see the reason why you would want a single shot connection?

        Why don't you simply call the function directly?

        That said, @jsulm is correct, calling disconnect is probably the correct approach. However it can be tricky and I would suggest using QMetaObject::Connection explicitly

        QMetaObject::Connection conn;
        conn = QObject::connect(sender, &Sender::signal, [=]() mutable {
            // Slot code to be executed
            // ...
        
            // Disconnect the connection
            QObject::disconnect(conn);
        });
        

        at least you don't end up with unnecessary object creations/allocations

        J Offline
        J Offline
        johnyang
        wrote on last edited by
        #5

        @J-Hilk I'm trying to implement a single shot connection waiting for an asynchronous response from http server. I'm curious if the connection in your code will be cleared when it gets out of scope?
        Should I do something like this instead:

        QMetaObject::Connection * const connection = new QMetaObject::Connection;
        *connection = connect(sender, &Sender::signal, [this, connection](){
        
            QObject::disconnect(*connection);
            delete connection;
        });
        
        J.HilkJ 1 Reply Last reply
        0
        • J johnyang

          @J-Hilk I'm trying to implement a single shot connection waiting for an asynchronous response from http server. I'm curious if the connection in your code will be cleared when it gets out of scope?
          Should I do something like this instead:

          QMetaObject::Connection * const connection = new QMetaObject::Connection;
          *connection = connect(sender, &Sender::signal, [this, connection](){
          
              QObject::disconnect(*connection);
              delete connection;
          });
          
          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #6

          @johnyang thats not needed, the framework manages the lambda internally. In this case the connection and lambda will be valid as long as the sender instance exists or disconnect was called.

          And stuff captured by lambdas does not go out of scope, as long as you don't explicitly capture by reference. As it makes its own copy.


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          1 Reply Last reply
          4
          • Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #7

            There is also a single shot connection type...

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            1 Reply Last reply
            8
            • GrecKoG Offline
              GrecKoG Offline
              GrecKo
              Qt Champions 2018
              wrote on last edited by
              #8

              @johnyang Is Sender a long lived object that sends signal multiple times?
              If not it might not be necessary to disconnect from it, similar to how we usually connect a lambda to QNetworkReply::finished without disconnecting after.
              And like Christian just said there's Qt::SingleShotConnection as parameter of QObject::connect since Qt 6.0

              J.HilkJ J 2 Replies Last reply
              2
              • GrecKoG GrecKo

                @johnyang Is Sender a long lived object that sends signal multiple times?
                If not it might not be necessary to disconnect from it, similar to how we usually connect a lambda to QNetworkReply::finished without disconnecting after.
                And like Christian just said there's Qt::SingleShotConnection as parameter of QObject::connect since Qt 6.0

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #9

                @GrecKo said in Destroy the signal/slot connection when the slot receives the signal:

                Qt::SingleShotConnection as parameter of QObject::connect since Qt 6.0

                Look at that!

                alt text


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                J 1 Reply Last reply
                3
                • J.HilkJ J.Hilk

                  @GrecKo said in Destroy the signal/slot connection when the slot receives the signal:

                  Qt::SingleShotConnection as parameter of QObject::connect since Qt 6.0

                  Look at that!

                  alt text

                  J Offline
                  J Offline
                  johnyang
                  wrote on last edited by
                  #10

                  @J-Hilk Unfortunately I'm still on Qt5 at the moment. I would love to get onto Qt6 soon. I have another question about using the disconnect approach. I have the following scenario:

                  QMetaObject::Connection * const connection = new QMetaObject::Connection;
                  *connection = connect(sender, &Sender::signal, [this, connection](){
                  
                      QObject::disconnect(*connection);
                      delete connection;
                      
                      // Some function that also sends out Sender::signal
                      Function();
                  
                  });
                  

                  Function() also sends out Sender::signal at the end. The above code seems to be working fine that the lambda function does not get triggered. However if I do the following, the lambda function does get triggered one more time (which is not what I want):

                  QMetaObject::Connection conn;
                  conn = QObject::connect(sender, &Sender::signal, [=]() {
                      // Disconnect the connection
                      QObject::disconnect(conn);
                  
                      // Some function that also sends out Sender::signal
                      Function();
                  });
                  

                  Is it alright to do what I did in the code above?

                  1 Reply Last reply
                  0
                  • GrecKoG GrecKo

                    @johnyang Is Sender a long lived object that sends signal multiple times?
                    If not it might not be necessary to disconnect from it, similar to how we usually connect a lambda to QNetworkReply::finished without disconnecting after.
                    And like Christian just said there's Qt::SingleShotConnection as parameter of QObject::connect since Qt 6.0

                    J Offline
                    J Offline
                    johnyang
                    wrote on last edited by johnyang
                    #11

                    @GrecKo Sender is a long lived object but I only want it to take place once for a logic reason. I am still on Qt5 at the moment so I can't use Qt::SingleShotConnection. However in my example code with unique pointer, is it a bad practice to reset context in the lambda function because it is owned by context?

                    QObject* pcontext = context.get();
                    connect(this, &SenderClass::send, pcontext, [this, context = std::move(context)] mutable
                    {
                        context.reset();
                        // do something when received the signal
                        Function();
                    });
                    
                    1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      johnyang
                      wrote on last edited by
                      #12

                      At the moment, the suggested code in https://www.kdab.com/single-shot-connections/ seems to work perfectly so far:

                      auto connection = std::make_unique<QMetaObject::Connection>();
                      auto connectionPtr = connection.get();
                      
                      auto singleShot = [receiver, connection = std::move(connection)](parameters) {
                        QObject::disconnect(*connection);
                        receiver->slot(parameters);
                      };
                      
                      *connectionPtr = connect(sender, &Sender::signal, receiver, std::move(singleShot)));
                      
                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        smada
                        wrote on last edited by
                        #13

                        This is my concern about the above:

                        int a = 5;
                        int b = 6;
                        auto connection = std::make_unique<QMetaObject::Connection>();
                        auto connectionPtr = connection.get();
                        
                        auto singleShot = [a, b, connection = std::move(connection)](parameters) {
                          QObject::disconnect(*connection);
                        
                          // Is the captured variable 'a' and 'b' still valid here? Or has this lambda been destroyed by
                          // the call to disconnect and thus 'a' and 'b' is no longer valid?
                          doSomethingWith(a, b);
                        };
                        
                        *connectionPtr = connect(sender, &Sender::signal, receiver, std::move(singleShot)));
                        

                        If the latter is true, (i.e. calling disconnect results in the lambda being destroyed) then we can no longer assume 'a' and 'b' are valid values. This could result in doSomethingWith(a, b) crashing, or worse not crashing because something else has occupied the address space of 'a' or 'b' and no longer represents the original value.

                        What I am ultimately asking here is, when does the lambda get destroyed after a disconnect is called?

                        1 Reply Last reply
                        0
                        • S Offline
                          S Offline
                          smada
                          wrote on last edited by
                          #14

                          I am just wondering if anyone has a answer of this?

                          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
                          • Unsolved