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. Disconnect all incoming and outgoing connections from QObject-derived class manually

Disconnect all incoming and outgoing connections from QObject-derived class manually

Scheduled Pinned Locked Moved Unsolved General and Desktop
23 Posts 6 Posters 7.4k 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.
  • A Offline
    A Offline
    Asperamanca
    wrote on last edited by
    #1

    I am trying to solve a crash caused by a slot called during destruction of my class. The problem is, that my own destructor has already run, but QObject's destructor has not yet run, so connections are still active.

    Since I don't just want to solve this one case, but prevent future cases like this, I'd like to move the disconnection of signals and slots to an earlier time, into a destructor of a custom base class of mine. That way, the offending slot would never be called.

    However, I have found no way according to docs to disconnect everything from an object both incoming and outgoing. No list of active connection in QObject or QMetaObject, either. The destructor in QObject does lots of internal stuff, but clearly doesn't use the public-interface disconnect (or similar) methods.

    Any ideas how I can safely disconnect everything to AND from and object?

    KroMignonK JKSHJ 2 Replies Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      If documentation is right, it should be enough to call:

      disconnect();
      

      or:

      QObject::disconnect(this, nullptr, nullptr, nullptr);
      

      See the docs

      (Z(:^

      JonBJ A 2 Replies Last reply
      1
      • sierdzioS sierdzio

        If documentation is right, it should be enough to call:

        disconnect();
        

        or:

        QObject::disconnect(this, nullptr, nullptr, nullptr);
        

        See the docs

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

        @sierdzio
        I think the OP is (also) asking to disconnect everywhere one of his objects is a slot to any signal. I think your second one does it where it's the signaller? Don't know about the first? Does either of these do it?

        B 1 Reply Last reply
        0
        • JonBJ JonB

          @sierdzio
          I think the OP is (also) asking to disconnect everywhere one of his objects is a slot to any signal. I think your second one does it where it's the signaller? Don't know about the first? Does either of these do it?

          B Offline
          B Offline
          Bonnie
          wrote on last edited by
          #4

          @JonB
          The first one is equivalent to the second.
          So both of them cannot disconnect the object's slots from "any object's signal", which is impossible.

          The sender may never be 0. (You cannot disconnect signals from more than one object in a single call.)

          A 1 Reply Last reply
          0
          • sierdzioS sierdzio

            If documentation is right, it should be enough to call:

            disconnect();
            

            or:

            QObject::disconnect(this, nullptr, nullptr, nullptr);
            

            See the docs

            A Offline
            A Offline
            Asperamanca
            wrote on last edited by
            #5

            @sierdzio said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

            If documentation is right, it should be enough to call:

            disconnect();
            

            or:

            QObject::disconnect(this, nullptr, nullptr, nullptr);
            

            See the docs

            The way I read the docs, this will only disconnect all signals of the object, but it will not disconnect slots connected to other object's signals

            1 Reply Last reply
            0
            • B Bonnie

              @JonB
              The first one is equivalent to the second.
              So both of them cannot disconnect the object's slots from "any object's signal", which is impossible.

              The sender may never be 0. (You cannot disconnect signals from more than one object in a single call.)

              A Offline
              A Offline
              Asperamanca
              wrote on last edited by
              #6

              @Bonnie said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

              @JonB
              The first one is equivalent to the second.
              So both of them cannot disconnect the object's slots from "any object's signal", which is impossible.

              The sender may never be 0. (You cannot disconnect signals from more than one object in a single call.)

              Impossible is a strong word, given that QObject's destructor seems to manage that

              B 1 Reply Last reply
              1
              • A Asperamanca

                @Bonnie said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                @JonB
                The first one is equivalent to the second.
                So both of them cannot disconnect the object's slots from "any object's signal", which is impossible.

                The sender may never be 0. (You cannot disconnect signals from more than one object in a single call.)

                Impossible is a strong word, given that QObject's destructor seems to manage that

                B Offline
                B Offline
                Bonnie
                wrote on last edited by
                #7

                @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                Impossible is a strong word, given that QObject's destructor seems to manage that

                Fine, impossible by calling disconnect

                1 Reply Last reply
                0
                • KroMignonK Offline
                  KroMignonK Offline
                  KroMignon
                  wrote on last edited by
                  #8
                  This post is deleted!
                  1 Reply Last reply
                  0
                  • A Asperamanca

                    I am trying to solve a crash caused by a slot called during destruction of my class. The problem is, that my own destructor has already run, but QObject's destructor has not yet run, so connections are still active.

                    Since I don't just want to solve this one case, but prevent future cases like this, I'd like to move the disconnection of signals and slots to an earlier time, into a destructor of a custom base class of mine. That way, the offending slot would never be called.

                    However, I have found no way according to docs to disconnect everything from an object both incoming and outgoing. No list of active connection in QObject or QMetaObject, either. The destructor in QObject does lots of internal stuff, but clearly doesn't use the public-interface disconnect (or similar) methods.

                    Any ideas how I can safely disconnect everything to AND from and object?

                    KroMignonK Offline
                    KroMignonK Offline
                    KroMignon
                    wrote on last edited by
                    #9

                    @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                    I am trying to solve a crash caused by a slot called during destruction of my class. The problem is, that my own destructor has already run, but QObject's destructor has not yet run, so connections are still active.

                    IMHO, you have a threading issue here.
                    For me, to call a slots during destructor, the call have to be started from another thread and the connection type is Qt::DirectConnection.

                    Perhaps you have to look at this?

                    A 1 Reply Last reply
                    0
                    • KroMignonK KroMignon

                      @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                      I am trying to solve a crash caused by a slot called during destruction of my class. The problem is, that my own destructor has already run, but QObject's destructor has not yet run, so connections are still active.

                      IMHO, you have a threading issue here.
                      For me, to call a slots during destructor, the call have to be started from another thread and the connection type is Qt::DirectConnection.

                      Perhaps you have to look at this?

                      A Offline
                      A Offline
                      Asperamanca
                      wrote on last edited by
                      #10

                      @KroMignon said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                      @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                      I am trying to solve a crash caused by a slot called during destruction of my class. The problem is, that my own destructor has already run, but QObject's destructor has not yet run, so connections are still active.

                      IMHO, you have a threading issue here.
                      For me, to call a slots during destructor, the call have to be started from another thread and the connection type is Qt::DirectConnection.

                      Perhaps you have to look at this?

                      No, it's quite clearly not a threading issue. Simply put, I have a custom editable text item derived from QGraphicsObject in a Graphics View hierarchy. If the item is destroyed, it notifies that editing was canceled through a signal.
                      Now I connected this signal to a slot of the text editor's parent item. The QGraphicsItem destructor of the parent item (which runs before the QObject destructor) destroys the child, which fires a signal to tell the world text editing was canceled, which calls the slot in my already half-destroyed parent item.

                      KroMignonK 1 Reply Last reply
                      0
                      • A Asperamanca

                        @KroMignon said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                        @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                        I am trying to solve a crash caused by a slot called during destruction of my class. The problem is, that my own destructor has already run, but QObject's destructor has not yet run, so connections are still active.

                        IMHO, you have a threading issue here.
                        For me, to call a slots during destructor, the call have to be started from another thread and the connection type is Qt::DirectConnection.

                        Perhaps you have to look at this?

                        No, it's quite clearly not a threading issue. Simply put, I have a custom editable text item derived from QGraphicsObject in a Graphics View hierarchy. If the item is destroyed, it notifies that editing was canceled through a signal.
                        Now I connected this signal to a slot of the text editor's parent item. The QGraphicsItem destructor of the parent item (which runs before the QObject destructor) destroys the child, which fires a signal to tell the world text editing was canceled, which calls the slot in my already half-destroyed parent item.

                        KroMignonK Offline
                        KroMignonK Offline
                        KroMignon
                        wrote on last edited by
                        #11

                        @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                        he QGraphicsItem destructor of the parent item (which runs before the QObject destructor) destroys the child, which fires a signal to tell the world text editing was canceled, which calls the slot in my already half-destroyed parent item.

                        One solution to avoid this loop is to avoid Qt::DirectConnection and force Qt::QueuedConnection for the cancel signal.
                        So the event is store in eventloop and QObject destructor will be called before the cancel event.
                        As instance has been destroyed, the event will be thrown by the QEventLoop.

                        A 1 Reply Last reply
                        3
                        • A Asperamanca

                          I am trying to solve a crash caused by a slot called during destruction of my class. The problem is, that my own destructor has already run, but QObject's destructor has not yet run, so connections are still active.

                          Since I don't just want to solve this one case, but prevent future cases like this, I'd like to move the disconnection of signals and slots to an earlier time, into a destructor of a custom base class of mine. That way, the offending slot would never be called.

                          However, I have found no way according to docs to disconnect everything from an object both incoming and outgoing. No list of active connection in QObject or QMetaObject, either. The destructor in QObject does lots of internal stuff, but clearly doesn't use the public-interface disconnect (or similar) methods.

                          Any ideas how I can safely disconnect everything to AND from and object?

                          JKSHJ Offline
                          JKSHJ Offline
                          JKSH
                          Moderators
                          wrote on last edited by JKSH
                          #12

                          @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                          I am trying to solve a crash caused by a slot called during destruction of my class. The problem is, that my own destructor has already run, but QObject's destructor has not yet run, so connections are still active.

                          Often, this can be prevented by using deleteLater() to delete your QObjects. This ensures that deletion only occurs after all signals have been processed.

                          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                          A 1 Reply Last reply
                          5
                          • KroMignonK KroMignon

                            @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                            he QGraphicsItem destructor of the parent item (which runs before the QObject destructor) destroys the child, which fires a signal to tell the world text editing was canceled, which calls the slot in my already half-destroyed parent item.

                            One solution to avoid this loop is to avoid Qt::DirectConnection and force Qt::QueuedConnection for the cancel signal.
                            So the event is store in eventloop and QObject destructor will be called before the cancel event.
                            As instance has been destroyed, the event will be thrown by the QEventLoop.

                            A Offline
                            A Offline
                            Asperamanca
                            wrote on last edited by
                            #13

                            @KroMignon said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                            @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                            he QGraphicsItem destructor of the parent item (which runs before the QObject destructor) destroys the child, which fires a signal to tell the world text editing was canceled, which calls the slot in my already half-destroyed parent item.

                            One solution to avoid this loop is to avoid Qt::DirectConnection and force Qt::QueuedConnection for the cancel signal.
                            So the event is store in eventloop and QObject destructor will be called before the cancel event.
                            As instance has been destroyed, the event will be thrown by the QEventLoop.

                            In this case, this would trigger another bug, since the timing of the signal is quite important in the 99 % of cases where the object is not destroyed. But in general, a solution worthy of consideration.

                            KroMignonK 1 Reply Last reply
                            0
                            • JKSHJ JKSH

                              @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                              I am trying to solve a crash caused by a slot called during destruction of my class. The problem is, that my own destructor has already run, but QObject's destructor has not yet run, so connections are still active.

                              Often, this can be prevented by using deleteLater() to delete your QObjects. This ensures that deletion only occurs after all signals have been processed.

                              A Offline
                              A Offline
                              Asperamanca
                              wrote on last edited by
                              #14

                              @JKSH said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                              @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                              I am trying to solve a crash caused by a slot called during destruction of my class. The problem is, that my own destructor has already run, but QObject's destructor has not yet run, so connections are still active.
                              

                              Often, this can be prevented by using deleteLater() to delete your QObjects. This ensures that deletion only occurs after all signals have been processed.

                              Not here, since GraphicsView will not play along and delete the object anyway...

                              1 Reply Last reply
                              0
                              • A Asperamanca

                                @KroMignon said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                he QGraphicsItem destructor of the parent item (which runs before the QObject destructor) destroys the child, which fires a signal to tell the world text editing was canceled, which calls the slot in my already half-destroyed parent item.

                                One solution to avoid this loop is to avoid Qt::DirectConnection and force Qt::QueuedConnection for the cancel signal.
                                So the event is store in eventloop and QObject destructor will be called before the cancel event.
                                As instance has been destroyed, the event will be thrown by the QEventLoop.

                                In this case, this would trigger another bug, since the timing of the signal is quite important in the 99 % of cases where the object is not destroyed. But in general, a solution worthy of consideration.

                                KroMignonK Offline
                                KroMignonK Offline
                                KroMignon
                                wrote on last edited by
                                #15

                                @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                In this case, this would trigger another bug, since the timing of the signal is quite important in the 99 % of cases where the object is not destroyed. But in general, a solution worthy of consideration.

                                You have to made a choice here, because you have a threading issue. Use queued connection is the easiest way, because it is the QEventLoop which will handle it for you.

                                Another approach, which is not so easy, would be to store QMetaObject::Connection returned by each connect() to the critical slots and disconnect then in your destructor.

                                A 1 Reply Last reply
                                0
                                • KroMignonK KroMignon

                                  @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                  In this case, this would trigger another bug, since the timing of the signal is quite important in the 99 % of cases where the object is not destroyed. But in general, a solution worthy of consideration.

                                  You have to made a choice here, because you have a threading issue. Use queued connection is the easiest way, because it is the QEventLoop which will handle it for you.

                                  Another approach, which is not so easy, would be to store QMetaObject::Connection returned by each connect() to the critical slots and disconnect then in your destructor.

                                  A Offline
                                  A Offline
                                  Asperamanca
                                  wrote on last edited by Asperamanca
                                  #16

                                  @KroMignon said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                  @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                  In this case, this would trigger another bug, since the timing of the signal is quite important in the 99 % of cases where the object is not destroyed. But in general, a solution worthy of consideration.

                                  You have to made a choice here, because you have a threading issue. Use queued connection is the easiest way, because it is the QEventLoop which will handle it for you.

                                  Another approach, which is not so easy, would be to store QMetaObject::Connection returned by each connect() to the critical slots and disconnect then in your destructor.

                                  Why do you believe so firmly it's a threading issue? It isn't, I see the call stack and the parallel stacks in debugger. Also, the behavior is easily explained for any QGraphicsObject, because the QGraphicsItem will delete it's child directly in the destructor, before the destructor of QObject runs (remember that you always have to derive from QObject first, so it's the last to destruct)

                                  EDIT: Also, I never used Qt::DirectConnection anywhere in 10 years of coding. So if it was multithreaded, the slot would be called queued.

                                  KroMignonK 1 Reply Last reply
                                  0
                                  • A Asperamanca

                                    @KroMignon said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                    @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                    In this case, this would trigger another bug, since the timing of the signal is quite important in the 99 % of cases where the object is not destroyed. But in general, a solution worthy of consideration.

                                    You have to made a choice here, because you have a threading issue. Use queued connection is the easiest way, because it is the QEventLoop which will handle it for you.

                                    Another approach, which is not so easy, would be to store QMetaObject::Connection returned by each connect() to the critical slots and disconnect then in your destructor.

                                    Why do you believe so firmly it's a threading issue? It isn't, I see the call stack and the parallel stacks in debugger. Also, the behavior is easily explained for any QGraphicsObject, because the QGraphicsItem will delete it's child directly in the destructor, before the destructor of QObject runs (remember that you always have to derive from QObject first, so it's the last to destruct)

                                    EDIT: Also, I never used Qt::DirectConnection anywhere in 10 years of coding. So if it was multithreaded, the slot would be called queued.

                                    KroMignonK Offline
                                    KroMignonK Offline
                                    KroMignon
                                    wrote on last edited by
                                    #17

                                    @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                    EDIT: Also, I never used Qt::DirectConnection anywhere in 10 years of coding. So if it was multithreaded, the slot would be called queued.

                                    If you are not specifying the connection type (Qt::AutoConnection) and sender/emitter are in same thread, it is same are using Qt::DirectConnection.
                                    So now you have an issue with this because signals are emitted during execution of your destructor and those signals are executing slots of your currently destroyed instance.
                                    If you have used Qt::QueuedConnection, you would not have this issue.

                                    I call this "threading issue", and yes it is not the right description. I apologize.

                                    JKSHJ 1 Reply Last reply
                                    1
                                    • KroMignonK KroMignon

                                      @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                      EDIT: Also, I never used Qt::DirectConnection anywhere in 10 years of coding. So if it was multithreaded, the slot would be called queued.

                                      If you are not specifying the connection type (Qt::AutoConnection) and sender/emitter are in same thread, it is same are using Qt::DirectConnection.
                                      So now you have an issue with this because signals are emitted during execution of your destructor and those signals are executing slots of your currently destroyed instance.
                                      If you have used Qt::QueuedConnection, you would not have this issue.

                                      I call this "threading issue", and yes it is not the right description. I apologize.

                                      JKSHJ Offline
                                      JKSHJ Offline
                                      JKSH
                                      Moderators
                                      wrote on last edited by
                                      #18

                                      @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                      @JKSH said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                      Often, this can be prevented by using deleteLater() to delete your QObjects. This ensures that deletion only occurs after all signals have been processed.

                                      Not here, since GraphicsView will not play along and delete the object anyway...

                                      Ah, I see the problem now.

                                      @KroMignon said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                      I call this "threading issue", and yes it is not the right description. I apologize.

                                      I'd say "sequencing issue" is a more correct term since everything is occurring on the same thread.

                                      Another approach, which is not so easy, would be to store QMetaObject::Connection returned by each connect() to the critical slots and disconnect then in your destructor.

                                      I can't think of any nice ways to fix @Asperamanca's problem if he wants to avoid Qt::QueuedConnection too. This solution is probably the best.

                                      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                      A 1 Reply Last reply
                                      0
                                      • JKSHJ JKSH

                                        @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                        @JKSH said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                        Often, this can be prevented by using deleteLater() to delete your QObjects. This ensures that deletion only occurs after all signals have been processed.

                                        Not here, since GraphicsView will not play along and delete the object anyway...

                                        Ah, I see the problem now.

                                        @KroMignon said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                        I call this "threading issue", and yes it is not the right description. I apologize.

                                        I'd say "sequencing issue" is a more correct term since everything is occurring on the same thread.

                                        Another approach, which is not so easy, would be to store QMetaObject::Connection returned by each connect() to the critical slots and disconnect then in your destructor.

                                        I can't think of any nice ways to fix @Asperamanca's problem if he wants to avoid Qt::QueuedConnection too. This solution is probably the best.

                                        A Offline
                                        A Offline
                                        Asperamanca
                                        wrote on last edited by
                                        #19

                                        @JKSH
                                        Well, I don't like the QueuedConnection solution because it would open a can of worms in order to close a different can of worms...

                                        Good solutions would be the ability to disconnect my slots (which disconnect() doesn't offer), or an ability to block my slots (there is a feature to block my signals, but not a similar one for slots).

                                        In the end, I made do with the non-generic, specific solution of manually disconnecting the offending slots in my own destructor.

                                        KroMignonK 1 Reply Last reply
                                        0
                                        • A Asperamanca

                                          @JKSH
                                          Well, I don't like the QueuedConnection solution because it would open a can of worms in order to close a different can of worms...

                                          Good solutions would be the ability to disconnect my slots (which disconnect() doesn't offer), or an ability to block my slots (there is a feature to block my signals, but not a similar one for slots).

                                          In the end, I made do with the non-generic, specific solution of manually disconnecting the offending slots in my own destructor.

                                          KroMignonK Offline
                                          KroMignonK Offline
                                          KroMignon
                                          wrote on last edited by
                                          #20

                                          @Asperamanca said in Disconnect all incoming and outgoing connections from QObject-derived class manually:

                                          In the end, I made do with the non-generic, specific solution of manually disconnecting the offending slots in my own destructor.

                                          It is normal that you don't have a generic solution, because, IMHO your code construction is not very clean. Updating a class when calling class destructor is a kind of "binding loop" issue.

                                          You can only disconnect signals from a class instance, because signal is the starting point. A class instance does not known which signal is connect to his slots, this made no sense, for example how should functor/lambda connection be recorded?

                                          If you want to disconnect slots, you have to store connect() result and use it to disconnect the slots.

                                          A 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