Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Using Signals in QGraphicsItem
Forum Update on Monday, May 27th 2025

Using Signals in QGraphicsItem

Scheduled Pinned Locked Moved Solved Qt for Python
25 Posts 5 Posters 1.3k 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 adrien-lsh
    25 Feb 2025, 09:04

    @JonB
    Yes that's what is happening. I am using PySide6 and here is an example:

    from PySide6.QtCore import QObject, QPointF, Signal
    from PySide6.QtGui import QPen, Qt
    from PySide6.QtWidgets import QApplication, QGraphicsItem, QGraphicsView, QGraphicsScene, QGraphicsLineItem
    
    
    class GraphicsView(QGraphicsView):
        def __init__(self, parent=None):
            super().__init__(parent)
            scene = QGraphicsScene()
            self.line = CroppingLine(0, 0, 100, 100)
            scene.addItem(self.line)
            self.setScene(scene)
    
    
    class CroppingLine(QGraphicsLineItem, QObject):
        moved = Signal(object, QPointF)
    
        def __init__(self, x1: float, y1: float, x2: float, y2: float):
            super().__init__(x1, y1, x2, y2)
            self.setPen(QPen(Qt.GlobalColor.blue, 3))
            self.setFlags(QGraphicsItem.GraphicsItemFlag.ItemIsMovable)
    
        def mouseMoveEvent(self, event):
            super().mouseMoveEvent(event)
            self.moved.emit(self, self.scenePos())
    
    if __name__ == '__main__':
        import sys
        app = QApplication(sys.argv)
        window = GraphicsView()
        window.show()
        sys.exit(app.exec())
    

    About the swap of the superclasses, I dont think it would work because the super().__init__() would not call QGraphicsLineItem init function but QObject's.

    J Offline
    J Offline
    JonB
    wrote on 25 Feb 2025, 09:12 last edited by JonB
    #12

    @adrien-lsh
    Before you make me try this, I did ask you put QObject first, that is at least required using C++/moc so I'd like you to test it. As I said, you should look up how super() works in Python, I think you can call something like super(QGraphicsLineItem).__init__() (actually it might be super(QGraphicsLineItem, self).__init__()?) if you need to, but you are the Python programmer!

    A 1 Reply Last reply 25 Feb 2025, 09:23
    0
    • J JonB
      25 Feb 2025, 09:12

      @adrien-lsh
      Before you make me try this, I did ask you put QObject first, that is at least required using C++/moc so I'd like you to test it. As I said, you should look up how super() works in Python, I think you can call something like super(QGraphicsLineItem).__init__() (actually it might be super(QGraphicsLineItem, self).__init__()?) if you need to, but you are the Python programmer!

      A Offline
      A Offline
      adrien-lsh
      wrote on 25 Feb 2025, 09:23 last edited by
      #13

      @JonB
      Nope it does not work with super(QGraphicsLineItem, self).__init__(...) because Python is trying to call the super class of QGraphicsLineItem which is QGraphicsItem and my class does not directly inherit from it so it doesnt work.

      I did achieve the inheritance swap using super(QObject, self).__init__(...) tho and my line displays correctly but it still crashes :/

      J 1 Reply Last reply 25 Feb 2025, 09:24
      0
      • A adrien-lsh
        25 Feb 2025, 09:23

        @JonB
        Nope it does not work with super(QGraphicsLineItem, self).__init__(...) because Python is trying to call the super class of QGraphicsLineItem which is QGraphicsItem and my class does not directly inherit from it so it doesnt work.

        I did achieve the inheritance swap using super(QObject, self).__init__(...) tho and my line displays correctly but it still crashes :/

        J Offline
        J Offline
        JonB
        wrote on 25 Feb 2025, 09:24 last edited by
        #14

        @adrien-lsh
        Since you seem to have provided a nice, standalone, complete example I can copy and paste --- unlike so many other people --- I will give it a play now....

        A J 2 Replies Last reply 25 Feb 2025, 09:31
        0
        • J JonB
          25 Feb 2025, 09:24

          @adrien-lsh
          Since you seem to have provided a nice, standalone, complete example I can copy and paste --- unlike so many other people --- I will give it a play now....

          A Offline
          A Offline
          adrien-lsh
          wrote on 25 Feb 2025, 09:31 last edited by
          #15

          @JonB
          Thanks! Let me know if you need any more information.

          1 Reply Last reply
          0
          • J JonB
            25 Feb 2025, 09:24

            @adrien-lsh
            Since you seem to have provided a nice, standalone, complete example I can copy and paste --- unlike so many other people --- I will give it a play now....

            J Offline
            J Offline
            JonB
            wrote on 25 Feb 2025, 09:31 last edited by
            #16

            @JonB
            Your code above, copied and pasted, works fine for me. Ubuntu 24.04, Qt 6.4.2, PySide6. Or at least I get an open window with a line in it. Could you be very specific about what you do to make it "crash"?

            A 1 Reply Last reply 25 Feb 2025, 09:32
            0
            • J JonB
              25 Feb 2025, 09:31

              @JonB
              Your code above, copied and pasted, works fine for me. Ubuntu 24.04, Qt 6.4.2, PySide6. Or at least I get an open window with a line in it. Could you be very specific about what you do to make it "crash"?

              A Offline
              A Offline
              adrien-lsh
              wrote on 25 Feb 2025, 09:32 last edited by
              #17

              @JonB
              Try to move the line.

              J 1 Reply Last reply 25 Feb 2025, 09:35
              0
              • A adrien-lsh
                25 Feb 2025, 09:32

                @JonB
                Try to move the line.

                J Offline
                J Offline
                JonB
                wrote on 25 Feb 2025, 09:35 last edited by
                #18

                @adrien-lsh
                Yeah, that's easier said than done! It's so thin, and I can't tell when I have actually grabbed it or not! Anyway I have reproed now, it does a SIGSEGV from

                0x00007ffff711fc14 in PySide::SignalManager::emitSignal(QObject*, char const*, _object*) ()
                   from /home/jon/.venv/pyside6/lib/python3.12/site-packages/PySide6/libpyside6.abi3.so.6.7
                (gdb) bt
                #0  0x00007ffff711fc14 in PySide::SignalManager::emitSignal(QObject*, char const*, _object*) ()
                    at /home/jon/.venv/pyside6/lib/python3.12/site-packages/PySide6/libpyside6.abi3.so.6.7
                

                Looking into that now...

                A 1 Reply Last reply 25 Feb 2025, 09:36
                0
                • J JonB
                  25 Feb 2025, 09:35

                  @adrien-lsh
                  Yeah, that's easier said than done! It's so thin, and I can't tell when I have actually grabbed it or not! Anyway I have reproed now, it does a SIGSEGV from

                  0x00007ffff711fc14 in PySide::SignalManager::emitSignal(QObject*, char const*, _object*) ()
                     from /home/jon/.venv/pyside6/lib/python3.12/site-packages/PySide6/libpyside6.abi3.so.6.7
                  (gdb) bt
                  #0  0x00007ffff711fc14 in PySide::SignalManager::emitSignal(QObject*, char const*, _object*) ()
                      at /home/jon/.venv/pyside6/lib/python3.12/site-packages/PySide6/libpyside6.abi3.so.6.7
                  

                  Looking into that now...

                  A Offline
                  A Offline
                  adrien-lsh
                  wrote on 25 Feb 2025, 09:36 last edited by
                  #19

                  @JonB
                  Yeah I should've set a bigger width ^^. Thank you.

                  J 1 Reply Last reply 25 Feb 2025, 09:50
                  0
                  • A adrien-lsh
                    25 Feb 2025, 09:36

                    @JonB
                    Yeah I should've set a bigger width ^^. Thank you.

                    J Offline
                    J Offline
                    JonB
                    wrote on 25 Feb 2025, 09:50 last edited by JonB
                    #20

                    @adrien-lsh
                    I think it is to do with the initialisation, requiring both inherited classes to be initialised. You were only doing so for the QGraphicsLineItem, not initialising the QObject. I find the following does work without crashing:

                    class CroppingLine(QObject, QGraphicsLineItem):
                        moved = Signal(object, QPointF)
                    
                        def __init__(self, x1: float, y1: float, x2: float, y2: float):
                            #super(QGraphicsLineItem, self).__init__(x1, y1, x2, y2)
                            QObject.__init__(self)
                            QGraphicsLineItem.__init__(self, x1, y1, x2, y2)
                    

                    There may be other ways of doing this with super() and/or not swapping the inheritance order, I just know this works fine.

                    A 1 Reply Last reply 25 Feb 2025, 10:03
                    1
                    • A adrien-lsh has marked this topic as solved on 25 Feb 2025, 10:03
                    • J JonB
                      25 Feb 2025, 09:50

                      @adrien-lsh
                      I think it is to do with the initialisation, requiring both inherited classes to be initialised. You were only doing so for the QGraphicsLineItem, not initialising the QObject. I find the following does work without crashing:

                      class CroppingLine(QObject, QGraphicsLineItem):
                          moved = Signal(object, QPointF)
                      
                          def __init__(self, x1: float, y1: float, x2: float, y2: float):
                              #super(QGraphicsLineItem, self).__init__(x1, y1, x2, y2)
                              QObject.__init__(self)
                              QGraphicsLineItem.__init__(self, x1, y1, x2, y2)
                      

                      There may be other ways of doing this with super() and/or not swapping the inheritance order, I just know this works fine.

                      A Offline
                      A Offline
                      adrien-lsh
                      wrote on 25 Feb 2025, 10:03 last edited by
                      #21

                      @JonB
                      Of course ! It never initialized the QObject so signals would never work.
                      Thank you for your help !

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on 25 Feb 2025, 10:23 last edited by SGaist
                        #22

                        Hi,

                        It's Python3, remove the class from your super calls. This should allow Python to do proper initialisation of the chain of classes (though sometimes it might fail for complex cases).

                        [Edit: we are in such a complex case]

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        J 1 Reply Last reply 25 Feb 2025, 10:27
                        0
                        • S SGaist
                          25 Feb 2025, 10:23

                          Hi,

                          It's Python3, remove the class from your super calls. This should allow Python to do proper initialisation of the chain of classes (though sometimes it might fail for complex cases).

                          [Edit: we are in such a complex case]

                          J Offline
                          J Offline
                          JonB
                          wrote on 25 Feb 2025, 10:27 last edited by JonB
                          #23

                          @SGaist
                          But the OP started with just

                          super().__init__(x1, y1, x2, y2)
                          

                          and, for whatever reason, that segments (later, on signal emit) because the QObject part has not been initialized, apparently. That is why I tried splitting it into two separate explicit initializations, which makes it work. So what exactly are you proposing?

                          S 1 Reply Last reply 25 Feb 2025, 11:18
                          0
                          • J JonB
                            25 Feb 2025, 10:27

                            @SGaist
                            But the OP started with just

                            super().__init__(x1, y1, x2, y2)
                            

                            and, for whatever reason, that segments (later, on signal emit) because the QObject part has not been initialized, apparently. That is why I tried splitting it into two separate explicit initializations, which makes it work. So what exactly are you proposing?

                            S Offline
                            S Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on 25 Feb 2025, 11:18 last edited by SGaist
                            #24

                            @JonB I misread the code !

                            We are in the territory where your solution (using __init__) is the way to go. Multiple inheritance in Python is quite tricky...

                            QObject expects an optional parent parameter which is not given here but it's not expecting the parameters for the QGraphicsLineItem constructor hence the failure. You can try to use the kwargs trick however it won't work either as it's not part of any of the method signature and thus can't work either.

                            Interested in AI ? www.idiap.ch
                            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                            1 Reply Last reply
                            0
                            • N Offline
                              N Offline
                              Nlight
                              wrote on 25 Feb 2025, 20:02 last edited by Nlight
                              #25
                              This post is deleted!
                              1 Reply Last reply
                              0

                              21/25

                              25 Feb 2025, 10:03

                              • Login

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