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. Pyside6 how to disconnect connection?
Forum Update on Monday, May 27th 2025

Pyside6 how to disconnect connection?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qgraphicssceneqgraphicsitemqobjesignal
34 Posts 5 Posters 12.6k 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.
  • E Offline
    E Offline
    eyllanesc
    wrote on 30 Dec 2020, 23:16 last edited by
    #10

    I see that many users are trying to help but because of the little information they are throwing things to see if one hits the wall but if you want quality help then generate the minimum space: the MRE

    1 Reply Last reply
    0
    • J jeremy_k
      30 Dec 2020, 23:14

      This might fall into that lambda exception I hinted at. If self is a QGraphicsItem, that isn't derived from QObject, and as such doesn't get the automatic disconnection behavior.

      https://doc.qt.io/qt-6/qobject.html#connect-4 is the C++ equivalent.

      D Offline
      D Offline
      Dariusz
      wrote on 30 Dec 2020, 23:17 last edited by
      #11

      @jeremy_k said in Pyside6 how to disconnect connection?:

      This might fall into that lambda exception I hinted at. If self is a QGraphicsItem, that isn't derived from QObject, and as such doesn't get the automatic disconnection behavior.

      https://doc.qt.io/qt-6/qobject.html#connect-4 is the C++ equivalent.

      I think that you are right. QGraphicsItem is not QObject, thus it does not have auto clean up functionality. I believe that's why I have to manually clean up connections.

      E 1 Reply Last reply 30 Dec 2020, 23:19
      0
      • E Offline
        E Offline
        eyllanesc
        wrote on 30 Dec 2020, 23:18 last edited by
        #12

        Note: Using shiboken2.delete does not remove the python object (the wrapper) but only the handled C++ object.

        D 1 Reply Last reply 30 Dec 2020, 23:19
        0
        • E eyllanesc
          30 Dec 2020, 23:18

          Note: Using shiboken2.delete does not remove the python object (the wrapper) but only the handled C++ object.

          D Offline
          D Offline
          Dariusz
          wrote on 30 Dec 2020, 23:19 last edited by
          #13

          @eyllanesc said in Pyside6 how to disconnect connection?:

          Note: Using shiboken2.delete does not remove the python object (the wrapper) but only the handled C++ object.

          This is frustrating... I miss C++ aff!
          So shibokeh delete the C++ obejct, how do I delete python Object? del self ?

          E J 2 Replies Last reply 30 Dec 2020, 23:21
          0
          • D Dariusz
            30 Dec 2020, 23:17

            @jeremy_k said in Pyside6 how to disconnect connection?:

            This might fall into that lambda exception I hinted at. If self is a QGraphicsItem, that isn't derived from QObject, and as such doesn't get the automatic disconnection behavior.

            https://doc.qt.io/qt-6/qobject.html#connect-4 is the C++ equivalent.

            I think that you are right. QGraphicsItem is not QObject, thus it does not have auto clean up functionality. I believe that's why I have to manually clean up connections.

            E Offline
            E Offline
            eyllanesc
            wrote on 30 Dec 2020, 23:19 last edited by
            #14

            @Dariusz The connection you show is not made by the QGraphicsItem but by the scene, so the one that removes the connection in the last instance is the scene.

            J 1 Reply Last reply 30 Dec 2020, 23:26
            0
            • D Dariusz
              30 Dec 2020, 23:19

              @eyllanesc said in Pyside6 how to disconnect connection?:

              Note: Using shiboken2.delete does not remove the python object (the wrapper) but only the handled C++ object.

              This is frustrating... I miss C++ aff!
              So shibokeh delete the C++ obejct, how do I delete python Object? del self ?

              E Offline
              E Offline
              eyllanesc
              wrote on 30 Dec 2020, 23:21 last edited by eyllanesc
              #15

              @Dariusz said in Pyside6 how to disconnect connection?:
              In python you can't delete an object, del only deletes the variable name but not the object(the memory space). I don't understand why deleting an item must imply deleting the connection that is in the scope of the scene.

              1 Reply Last reply
              0
              • D Dariusz
                30 Dec 2020, 23:19

                @eyllanesc said in Pyside6 how to disconnect connection?:

                Note: Using shiboken2.delete does not remove the python object (the wrapper) but only the handled C++ object.

                This is frustrating... I miss C++ aff!
                So shibokeh delete the C++ obejct, how do I delete python Object? del self ?

                J Offline
                J Offline
                jeremy_k
                wrote on 30 Dec 2020, 23:21 last edited by
                #16

                @Dariusz said in Pyside6 how to disconnect connection?:

                @eyllanesc said in Pyside6 how to disconnect connection?:

                Note: Using shiboken2.delete does not remove the python object (the wrapper) but only the handled C++ object.

                This is frustrating... I miss C++ aff!
                So shibokeh delete the C++ obejct, how do I delete python Object? del self ?

                That, or remove all references to the item. If the object isn't referenced via a variable that is in scope somewhere else, the python garbage collector should eventually clean up.

                Asking a question about code? http://eel.is/iso-c++/testcase/

                E 1 Reply Last reply 30 Dec 2020, 23:22
                0
                • J jeremy_k
                  30 Dec 2020, 23:21

                  @Dariusz said in Pyside6 how to disconnect connection?:

                  @eyllanesc said in Pyside6 how to disconnect connection?:

                  Note: Using shiboken2.delete does not remove the python object (the wrapper) but only the handled C++ object.

                  This is frustrating... I miss C++ aff!
                  So shibokeh delete the C++ obejct, how do I delete python Object? del self ?

                  That, or remove all references to the item. If the object isn't referenced via a variable that is in scope somewhere else, the python garbage collector should eventually clean up.

                  E Offline
                  E Offline
                  eyllanesc
                  wrote on 30 Dec 2020, 23:22 last edited by
                  #17

                  @jeremy_k Exactly, that's why I think the OP has an XY problem

                  D 1 Reply Last reply 30 Dec 2020, 23:23
                  0
                  • E eyllanesc
                    30 Dec 2020, 23:22

                    @jeremy_k Exactly, that's why I think the OP has an XY problem

                    D Offline
                    D Offline
                    Dariusz
                    wrote on 30 Dec 2020, 23:23 last edited by
                    #18

                    @eyllanesc said in Pyside6 how to disconnect connection?:

                    @jeremy_k Exactly, that's why I think the OP has an XY problem

                    Well the initial signal problem is now solved. Since I delete items and scene remain active, scene does not clean up connections. So I have to manually clean them up.

                    My second problem is how to properly delete a qgraphicsitem with its children in python. Perhaps I should make another topic for that as this one has solved my main issue.

                    E 1 Reply Last reply 30 Dec 2020, 23:26
                    0
                    • D Dariusz
                      30 Dec 2020, 23:23

                      @eyllanesc said in Pyside6 how to disconnect connection?:

                      @jeremy_k Exactly, that's why I think the OP has an XY problem

                      Well the initial signal problem is now solved. Since I delete items and scene remain active, scene does not clean up connections. So I have to manually clean them up.

                      My second problem is how to properly delete a qgraphicsitem with its children in python. Perhaps I should make another topic for that as this one has solved my main issue.

                      E Offline
                      E Offline
                      eyllanesc
                      wrote on 30 Dec 2020, 23:26 last edited by
                      #19

                      @Dariusz I don't understand how you have solved your current problem, and so far I don't understand what the connection (or disconnection) of the pinReleaseEvent signal of the scene has to do with the elimination of an item since they are 2 different objects. If anyone understands please explain it to me

                      1 Reply Last reply
                      1
                      • E eyllanesc
                        30 Dec 2020, 23:19

                        @Dariusz The connection you show is not made by the QGraphicsItem but by the scene, so the one that removes the connection in the last instance is the scene.

                        J Offline
                        J Offline
                        jeremy_k
                        wrote on 30 Dec 2020, 23:26 last edited by
                        #20

                        @eyllanesc said in Pyside6 how to disconnect connection?:

                        @Dariusz The connection you show is not made by the QGraphicsItem but by the scene, so the one that removes the connection in the last instance is the scene.

                        The issue is that the QGraphicsItem is on the receiving end of the connection, and is effectively captured. The caller doesn't know that the captured item is no longer valid, leading to an invalid condition at call time. In C++, it would be undefined behavior. I don't know what the python terminology is.

                        Generic C++ example:

                        int *i = new int;
                        *i = 0;
                        auto f = [i]() { *i++; };
                        delete i;
                        f();
                        

                        Asking a question about code? http://eel.is/iso-c++/testcase/

                        E 1 Reply Last reply 30 Dec 2020, 23:29
                        0
                        • J jeremy_k
                          30 Dec 2020, 23:26

                          @eyllanesc said in Pyside6 how to disconnect connection?:

                          @Dariusz The connection you show is not made by the QGraphicsItem but by the scene, so the one that removes the connection in the last instance is the scene.

                          The issue is that the QGraphicsItem is on the receiving end of the connection, and is effectively captured. The caller doesn't know that the captured item is no longer valid, leading to an invalid condition at call time. In C++, it would be undefined behavior. I don't know what the python terminology is.

                          Generic C++ example:

                          int *i = new int;
                          *i = 0;
                          auto f = [i]() { *i++; };
                          delete i;
                          f();
                          
                          E Offline
                          E Offline
                          eyllanesc
                          wrote on 30 Dec 2020, 23:29 last edited by
                          #21

                          @jeremy_k The question is the following: in bindings such as PySide or PyQt, the ownership of the items is held by the scene, so when you remove the item from the scene then the item has no ownership and is eventually removed by the python GC (python is not C++), and at the time the GC removes the python object it also removes its connections.

                          D 1 Reply Last reply 30 Dec 2020, 23:34
                          0
                          • E eyllanesc
                            30 Dec 2020, 23:29

                            @jeremy_k The question is the following: in bindings such as PySide or PyQt, the ownership of the items is held by the scene, so when you remove the item from the scene then the item has no ownership and is eventually removed by the python GC (python is not C++), and at the time the GC removes the python object it also removes its connections.

                            D Offline
                            D Offline
                            Dariusz
                            wrote on 30 Dec 2020, 23:34 last edited by
                            #22

                            @eyllanesc said in Pyside6 how to disconnect connection?:

                            @jeremy_k The question is the following: in bindings such as PySide or PyQt, the ownership of the items is held by the scene, so when you remove the item from the scene then the item has no ownership and is eventually removed by the python GC (python is not C++), and at the time the GC removes the python object it also removes its connections.

                            Unles signal holds a pointer to object and thus it will never get deleted... since scene didn't disconnect the signal since scene.removeItem() does not delete the item, nor item is QObject so its treated as lambda function (I guess?) as @jeremy_k suggested...

                            E 1 Reply Last reply 30 Dec 2020, 23:38
                            0
                            • D Dariusz
                              30 Dec 2020, 23:34

                              @eyllanesc said in Pyside6 how to disconnect connection?:

                              @jeremy_k The question is the following: in bindings such as PySide or PyQt, the ownership of the items is held by the scene, so when you remove the item from the scene then the item has no ownership and is eventually removed by the python GC (python is not C++), and at the time the GC removes the python object it also removes its connections.

                              Unles signal holds a pointer to object and thus it will never get deleted... since scene didn't disconnect the signal since scene.removeItem() does not delete the item, nor item is QObject so its treated as lambda function (I guess?) as @jeremy_k suggested...

                              E Offline
                              E Offline
                              eyllanesc
                              wrote on 30 Dec 2020, 23:38 last edited by eyllanesc
                              #23

                              @Dariusz To provide what I indicate I can provide a MWE, where every 1 second a signal is emitted and that is connected to an item, in the fifth second the item is removed but it does not cause any error.

                              from PySide6 import QtCore, QtWidgets
                              
                              
                              class FooItem(QtWidgets.QGraphicsEllipseItem):
                                  def foo_slot(self):
                                      print("slot")
                              
                              
                              class Scene(QtWidgets.QGraphicsScene):
                                  fooSignal = QtCore.Signal()
                              
                              
                              class View(QtWidgets.QGraphicsView):
                                  def __init__(self, parent=None):
                                      super().__init__(parent)
                              
                                      scene = Scene(self)
                                      self.setScene(scene)
                              
                                      timer = QtCore.QTimer(self, interval=1000)
                                      timer.timeout.connect(self.scene().fooSignal)
                                      timer.start()
                              
                                      item = FooItem()
                                      self.scene().addItem(item)
                              
                                      self.scene().fooSignal.connect(item.foo_slot)
                              
                                      QtCore.QTimer.singleShot(5000, self.remove_item)
                              
                                  def remove_item(self):
                                      items = self.scene().items()
                                      if items:
                                          item = items[0]
                                          self.scene().removeItem(item)
                              
                              
                              if __name__ == "__main__":
                                  app = QtWidgets.QApplication([])
                                  w = View()
                                  w.show()
                                  app.exec_()
                              

                              Output:

                              slot
                              slot
                              slot
                              slot
                              slot
                              
                              D 1 Reply Last reply 30 Dec 2020, 23:46
                              1
                              • E eyllanesc
                                30 Dec 2020, 23:38

                                @Dariusz To provide what I indicate I can provide a MWE, where every 1 second a signal is emitted and that is connected to an item, in the fifth second the item is removed but it does not cause any error.

                                from PySide6 import QtCore, QtWidgets
                                
                                
                                class FooItem(QtWidgets.QGraphicsEllipseItem):
                                    def foo_slot(self):
                                        print("slot")
                                
                                
                                class Scene(QtWidgets.QGraphicsScene):
                                    fooSignal = QtCore.Signal()
                                
                                
                                class View(QtWidgets.QGraphicsView):
                                    def __init__(self, parent=None):
                                        super().__init__(parent)
                                
                                        scene = Scene(self)
                                        self.setScene(scene)
                                
                                        timer = QtCore.QTimer(self, interval=1000)
                                        timer.timeout.connect(self.scene().fooSignal)
                                        timer.start()
                                
                                        item = FooItem()
                                        self.scene().addItem(item)
                                
                                        self.scene().fooSignal.connect(item.foo_slot)
                                
                                        QtCore.QTimer.singleShot(5000, self.remove_item)
                                
                                    def remove_item(self):
                                        items = self.scene().items()
                                        if items:
                                            item = items[0]
                                            self.scene().removeItem(item)
                                
                                
                                if __name__ == "__main__":
                                    app = QtWidgets.QApplication([])
                                    w = View()
                                    w.show()
                                    app.exec_()
                                

                                Output:

                                slot
                                slot
                                slot
                                slot
                                slot
                                
                                D Offline
                                D Offline
                                Dariusz
                                wrote on 30 Dec 2020, 23:46 last edited by
                                #24

                                @eyllanesc You are right, this works as it should. I must have more issues elsewhere and the "disconnect" signal solution I found must not be fixing the larger issue I have :- (

                                E 1 Reply Last reply 30 Dec 2020, 23:48
                                0
                                • J Offline
                                  J Offline
                                  jeremy_k
                                  wrote on 30 Dec 2020, 23:47 last edited by
                                  #25

                                  The code I had issues with, using PyQt5, is:

                                  from PyQt5.QtCore import QObject
                                  obj1 = QObject()
                                  obj2 = QObject()
                                  obj1.destroyed.connect(lambda: obj2.deleteLater())
                                  del obj2
                                  del obj1
                                  

                                  Here, the capture is explicit, and the punishment is swift:

                                  Traceback (most recent call last):
                                  File "<stdin>", line 1, in <lambda>
                                  NameError: name 'obj2' is not defined
                                  Abort trap: 6
                                  

                                  Asking a question about code? http://eel.is/iso-c++/testcase/

                                  E SGaistS 2 Replies Last reply 30 Dec 2020, 23:51
                                  0
                                  • D Dariusz
                                    30 Dec 2020, 23:46

                                    @eyllanesc You are right, this works as it should. I must have more issues elsewhere and the "disconnect" signal solution I found must not be fixing the larger issue I have :- (

                                    E Offline
                                    E Offline
                                    eyllanesc
                                    wrote on 30 Dec 2020, 23:48 last edited by
                                    #26

                                    @Dariusz That is why I say that it provides an MRE, you will not expect the community to be crazy throwing papers on the wall waiting for one to stick.

                                    D 1 Reply Last reply 30 Dec 2020, 23:54
                                    0
                                    • J jeremy_k
                                      30 Dec 2020, 23:47

                                      The code I had issues with, using PyQt5, is:

                                      from PyQt5.QtCore import QObject
                                      obj1 = QObject()
                                      obj2 = QObject()
                                      obj1.destroyed.connect(lambda: obj2.deleteLater())
                                      del obj2
                                      del obj1
                                      

                                      Here, the capture is explicit, and the punishment is swift:

                                      Traceback (most recent call last):
                                      File "<stdin>", line 1, in <lambda>
                                      NameError: name 'obj2' is not defined
                                      Abort trap: 6
                                      
                                      E Offline
                                      E Offline
                                      eyllanesc
                                      wrote on 30 Dec 2020, 23:51 last edited by eyllanesc
                                      #27

                                      @jeremy_k First of all GC only removes the objects that have no references.

                                      The problem is very different, in principle when deleteLater is called it deletes the C ++ object and then a reference to the python object is eliminated, if it no longer has references the object would be eliminated as I already indicated, but in your particular case the lambda method has a scope so it has a reference and therefore the python object (the wrapper) will not be eliminated but the C ++ object

                                      E 1 Reply Last reply 30 Dec 2020, 23:55
                                      0
                                      • E eyllanesc
                                        30 Dec 2020, 23:48

                                        @Dariusz That is why I say that it provides an MRE, you will not expect the community to be crazy throwing papers on the wall waiting for one to stick.

                                        D Offline
                                        D Offline
                                        Dariusz
                                        wrote on 30 Dec 2020, 23:54 last edited by
                                        #28

                                        @eyllanesc said in Pyside6 how to disconnect connection?:

                                        @Dariusz That is why I say that it provides an MRE, you will not expect the community to be crazy throwing papers on the wall waiting for one to stick.

                                        Yes I understand your point, however, the app I'm working on has 150+ files and few thousand lines of code... Doing simple example usually "solve my issues", but my issues are not simple and solving them is quite "hard"... so I'm trying to ask for a "simple" answer to the question like... how to properly disconnect a signal if I have to do it manually and I don't want to rely on automatic qt logic... I guess I'm "old fashion" I like to manage my memory myself and python is a bit... "leme do it memememe" and I never know if he does it or not :- )

                                        E 1 Reply Last reply 30 Dec 2020, 23:58
                                        0
                                        • E eyllanesc
                                          30 Dec 2020, 23:51

                                          @jeremy_k First of all GC only removes the objects that have no references.

                                          The problem is very different, in principle when deleteLater is called it deletes the C ++ object and then a reference to the python object is eliminated, if it no longer has references the object would be eliminated as I already indicated, but in your particular case the lambda method has a scope so it has a reference and therefore the python object (the wrapper) will not be eliminated but the C ++ object

                                          E Offline
                                          E Offline
                                          eyllanesc
                                          wrote on 30 Dec 2020, 23:55 last edited by
                                          #29
                                          This post is deleted!
                                          1 Reply Last reply
                                          0

                                          19/34

                                          30 Dec 2020, 23:26

                                          • Login

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