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. QGestureRecognizer.registerRecognizer() crashes using PySide2
Forum Updated to NodeBB v4.3 + New Features

QGestureRecognizer.registerRecognizer() crashes using PySide2

Scheduled Pinned Locked Moved Unsolved Qt for Python
19 Posts 4 Posters 1.8k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N nutrx

    I'm trying to register custom gestures in a QGraphicsView using PySide2. Calling

            pan_gesture_id = QGestureRecognizer.registerRecognizer(recognizer)
    

    results in a crash without any error. I couldn't find anything in the docs specifying the process of registering a gesture recognizer using PySide2. The following example reproduces the crash:

    class View(QGraphicsView):
        def __init__(self):
            super().__init__()
            scene = QGraphicsScene(self)
            scene.setSceneRect(0, 0, self.width(), self.height())
            self.setScene(scene)
    
            recognizer = PanGestureRecognizer()
            pan_gesture_id = QGestureRecognizer.registerRecognizer(recognizer)
            self.grabGesture(pan_gesture_id)
    

    am I missing anything there?

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

    @nutrx
    If you have PyQt5 installed/available, the usual is to try it there. If same code works, blame PySide2....

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #3

      Hi,

      Can you provide the full script you use to trigger the crash ?

      By the way:

      • which version of PySide2 are you using ?
      • which version of Python ?
      • on which OS ?
      • how did you install PySide2 ?

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

      N 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        Can you provide the full script you use to trigger the crash ?

        By the way:

        • which version of PySide2 are you using ?
        • which version of Python ?
        • on which OS ?
        • how did you install PySide2 ?
        N Offline
        N Offline
        nutrx
        wrote on last edited by
        #4

        @SGaist sorry, should've added that

        from PySide2.QtWidgets import QMainWindow, QApplication, QGraphicsView, QGraphicsScene, QGestureRecognizer, QGesture
        from PySide2.QtGui import QTouchEvent
        from PySide2.QtCore import QEvent
        
        
        class PanGesture(QGesture):
            def __init__(self, parent=None):
                super().__init__(parent)
        
                self.pos = None
                self.press = None
                self.last = None
        
        class PanGestureRecognizer(QGestureRecognizer):
            """Not complete, just some test"""
            def create(self, target) -> QGesture:
                return PanGesture()
        
            def reset(self, state: QGesture) -> None:
                pass
        
            def recognize(self, state: QGesture, watched, event: QEvent) -> QGestureRecognizer.Result:
                if event.type() == QEvent.TouchBegin:
                    touch_event: QTouchEvent = event
                    if len(touch_event.touchPoints()) == 1:
                        state.press = touch_event.touchPoints()[0]
                        state.pos = state.press
                        return QGestureRecognizer.MayBeGesture
                elif event.type() == QEvent.TouchUpdate:
                    touch_event: QTouchEvent = event
                    state.last = state.pos
                    state.pos = touch_event.touchPoints()[0]
                    return QGestureRecognizer.TriggerGesture
        
        class View(QGraphicsView):
            def __init__(self):
                super().__init__()
        
                scene = QGraphicsScene(self)
                scene.setSceneRect(0, 0, self.width(), self.height())
                self.setScene(scene)
        
                recognizer = PanGestureRecognizer()
                pan_gesture_id = QGestureRecognizer.registerRecognizer(recognizer)
                self.grabGesture(pan_gesture_id)
        
        class ViewWindow(QMainWindow):
            def __init__(self):
                super().__init__()
                self.setCentralWidget(View())
        
        if __name__ == '__main__':
            app = QApplication()
            widget = ViewWindow()
            widget.show()
            app.exec_()
        
        

        see View's constructor.

        • PySide2 5.15.2, installed via pip, inside python virtual environment
        • Python 3.9.0
        • Windows 10

        the GestureRecognizer probably doesn't work, I had just quickly put that together for some tests, but since I don't see any runtime error, I assume it's not the class custom GestureRecognizer what's causing the crash

        jeremy_kJ 1 Reply Last reply
        0
        • N nutrx

          @SGaist sorry, should've added that

          from PySide2.QtWidgets import QMainWindow, QApplication, QGraphicsView, QGraphicsScene, QGestureRecognizer, QGesture
          from PySide2.QtGui import QTouchEvent
          from PySide2.QtCore import QEvent
          
          
          class PanGesture(QGesture):
              def __init__(self, parent=None):
                  super().__init__(parent)
          
                  self.pos = None
                  self.press = None
                  self.last = None
          
          class PanGestureRecognizer(QGestureRecognizer):
              """Not complete, just some test"""
              def create(self, target) -> QGesture:
                  return PanGesture()
          
              def reset(self, state: QGesture) -> None:
                  pass
          
              def recognize(self, state: QGesture, watched, event: QEvent) -> QGestureRecognizer.Result:
                  if event.type() == QEvent.TouchBegin:
                      touch_event: QTouchEvent = event
                      if len(touch_event.touchPoints()) == 1:
                          state.press = touch_event.touchPoints()[0]
                          state.pos = state.press
                          return QGestureRecognizer.MayBeGesture
                  elif event.type() == QEvent.TouchUpdate:
                      touch_event: QTouchEvent = event
                      state.last = state.pos
                      state.pos = touch_event.touchPoints()[0]
                      return QGestureRecognizer.TriggerGesture
          
          class View(QGraphicsView):
              def __init__(self):
                  super().__init__()
          
                  scene = QGraphicsScene(self)
                  scene.setSceneRect(0, 0, self.width(), self.height())
                  self.setScene(scene)
          
                  recognizer = PanGestureRecognizer()
                  pan_gesture_id = QGestureRecognizer.registerRecognizer(recognizer)
                  self.grabGesture(pan_gesture_id)
          
          class ViewWindow(QMainWindow):
              def __init__(self):
                  super().__init__()
                  self.setCentralWidget(View())
          
          if __name__ == '__main__':
              app = QApplication()
              widget = ViewWindow()
              widget.show()
              app.exec_()
          
          

          see View's constructor.

          • PySide2 5.15.2, installed via pip, inside python virtual environment
          • Python 3.9.0
          • Windows 10

          the GestureRecognizer probably doesn't work, I had just quickly put that together for some tests, but since I don't see any runtime error, I assume it's not the class custom GestureRecognizer what's causing the crash

          jeremy_kJ Offline
          jeremy_kJ Offline
          jeremy_k
          wrote on last edited by
          #5

          After converting the example to run with PyQt5:

          $ python3 main.py 
          TypeError: invalid result from PanGestureRecognizer.recognize(), NoneType cannot be converted to PyQt5.QtWidgets.Result in this context
          Abort trap: 6
          

          PanGestureRecognizer.recognize is falling off the end and effectively returning None for anything other than a TouchBegin or TouchUpdate.

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

          N 1 Reply Last reply
          0
          • jeremy_kJ jeremy_k

            After converting the example to run with PyQt5:

            $ python3 main.py 
            TypeError: invalid result from PanGestureRecognizer.recognize(), NoneType cannot be converted to PyQt5.QtWidgets.Result in this context
            Abort trap: 6
            

            PanGestureRecognizer.recognize is falling off the end and effectively returning None for anything other than a TouchBegin or TouchUpdate.

            N Offline
            N Offline
            nutrx
            wrote on last edited by
            #6

            @jeremy_k yes absolutely, I didn't pay attention to that method, because it still fails if I ignore otherwise, or everything from the beginning

                def recognize(self, state: QGesture, watched, event: QEvent) -> QGestureRecognizer.Result:
                    return QGestureRecognizer.Ignore
            

            or in the example above:

                def recognize(self, state: QGesture, watched, event: QEvent) -> QGestureRecognizer.Result:
                    if event.type() == QEvent.TouchBegin:
                        touch_event: QTouchEvent = event
                        if len(touch_event.touchPoints()) == 1:
                            state.press = touch_event.touchPoints()[0]
                            state.pos = state.press
                            return QGestureRecognizer.MayBeGesture
                    elif event.type() == QEvent.TouchUpdate:
                        touch_event: QTouchEvent = event
                        state.last = state.pos
                        state.pos = touch_event.touchPoints()[0]
                        return QGestureRecognizer.TriggerGesture
                    return QGestureRecognizer.Ignore
            

            Shouldn't that be sufficient?

            jeremy_kJ 1 Reply Last reply
            0
            • N nutrx

              @jeremy_k yes absolutely, I didn't pay attention to that method, because it still fails if I ignore otherwise, or everything from the beginning

                  def recognize(self, state: QGesture, watched, event: QEvent) -> QGestureRecognizer.Result:
                      return QGestureRecognizer.Ignore
              

              or in the example above:

                  def recognize(self, state: QGesture, watched, event: QEvent) -> QGestureRecognizer.Result:
                      if event.type() == QEvent.TouchBegin:
                          touch_event: QTouchEvent = event
                          if len(touch_event.touchPoints()) == 1:
                              state.press = touch_event.touchPoints()[0]
                              state.pos = state.press
                              return QGestureRecognizer.MayBeGesture
                      elif event.type() == QEvent.TouchUpdate:
                          touch_event: QTouchEvent = event
                          state.last = state.pos
                          state.pos = touch_event.touchPoints()[0]
                          return QGestureRecognizer.TriggerGesture
                      return QGestureRecognizer.Ignore
              

              Shouldn't that be sufficient?

              jeremy_kJ Offline
              jeremy_kJ Offline
              jeremy_k
              wrote on last edited by
              #7

              @nutrx said in QGestureRecognizer.registerRecognizer() crashes using PySide2:

              @jeremy_k yes absolutely, I didn't pay attention to that method, because it still fails if I ignore otherwise, or everything from the beginning

                  def recognize(self, state: QGesture, watched, event: QEvent) -> QGestureRecognizer.Result:
                      return QGestureRecognizer.Ignore
              

              ...

              Shouldn't that be sufficient?

              I'm not sure what you mean here. With the addition of the default Ignore, the application displays a window and doesn't do anything noteworthy in my environment. Are you still experiencing a crash?

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

              N 1 Reply Last reply
              0
              • jeremy_kJ jeremy_k

                @nutrx said in QGestureRecognizer.registerRecognizer() crashes using PySide2:

                @jeremy_k yes absolutely, I didn't pay attention to that method, because it still fails if I ignore otherwise, or everything from the beginning

                    def recognize(self, state: QGesture, watched, event: QEvent) -> QGestureRecognizer.Result:
                        return QGestureRecognizer.Ignore
                

                ...

                Shouldn't that be sufficient?

                I'm not sure what you mean here. With the addition of the default Ignore, the application displays a window and doesn't do anything noteworthy in my environment. Are you still experiencing a crash?

                N Offline
                N Offline
                nutrx
                wrote on last edited by
                #8

                @jeremy_k yes, exactly. I just tried to get it to run, so I could move on from there. But it still crashes the same as before. Sorry, I don't have PyQt set up rn

                jeremy_kJ 1 Reply Last reply
                0
                • N nutrx

                  @jeremy_k yes, exactly. I just tried to get it to run, so I could move on from there. But it still crashes the same as before. Sorry, I don't have PyQt set up rn

                  jeremy_kJ Offline
                  jeremy_kJ Offline
                  jeremy_k
                  wrote on last edited by
                  #9

                  PanGestureRecognizer doesn't have an __init__ to call QGestureRecognizer.__init__. I vaguely recall reports of misbehavior using PyQt if a Qt object's constructor isn't invoked. This may have been limited to QObjects. It might not apply to PySide. Either way, it's an inexpensive experiment to run. QGestureRecognizer's C++ constructor is empty, but there may be some bookkeeping on the Python side.

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

                  N 1 Reply Last reply
                  0
                  • jeremy_kJ jeremy_k

                    PanGestureRecognizer doesn't have an __init__ to call QGestureRecognizer.__init__. I vaguely recall reports of misbehavior using PyQt if a Qt object's constructor isn't invoked. This may have been limited to QObjects. It might not apply to PySide. Either way, it's an inexpensive experiment to run. QGestureRecognizer's C++ constructor is empty, but there may be some bookkeeping on the Python side.

                    N Offline
                    N Offline
                    nutrx
                    wrote on last edited by
                    #10

                    @jeremy_k you mean, I should try just calling QGestureRecognizer's __init__ in PanGestureRecognizer.__init__? I would've guessed that's ambiguous, or does instanciation lead to a direct call of the C++ parent constructor instead of the parent's __init__ in Python? However, I just tried, still no luck :/

                    jeremy_kJ 1 Reply Last reply
                    0
                    • N nutrx

                      @jeremy_k you mean, I should try just calling QGestureRecognizer's __init__ in PanGestureRecognizer.__init__? I would've guessed that's ambiguous, or does instanciation lead to a direct call of the C++ parent constructor instead of the parent's __init__ in Python? However, I just tried, still no luck :/

                      jeremy_kJ Offline
                      jeremy_kJ Offline
                      jeremy_k
                      wrote on last edited by
                      #11
                      class PanGestureRecognizer(QGestureRecognizer):
                          def __init__(self):
                              super().__init__()
                      

                      This doesn't seem to be necessary with pure python classes. The wording of object.__init__ led me to believe that it was, but a test suggests that the base class __init__ is called if no derived __init__ is defined.

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

                      JonBJ 1 Reply Last reply
                      0
                      • jeremy_kJ jeremy_k
                        class PanGestureRecognizer(QGestureRecognizer):
                            def __init__(self):
                                super().__init__()
                        

                        This doesn't seem to be necessary with pure python classes. The wording of object.__init__ led me to believe that it was, but a test suggests that the base class __init__ is called if no derived __init__ is defined.

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

                        @jeremy_k
                        Well, in Python just like in, say, C++, if you do not define your own __init__() (constructor in C++) the language will always cause the base class's __init__()/constructor. If you do define your own, you must then explicitly call the base class __init__()/constructor, in either language. in Python.

                        [EDIT As @jeremy_k pointed out below, I was wrong to say this applies in all C++ cases. Let's leave it as: in Python, if you define any derived __init__() you must (should) explicitly call the base __init__() from there; but if you do not define a derived __init__() the base one will still be called.]

                        I vaguely recall reports of misbehavior using PyQt if a Qt object's constructor isn't invoked

                        I don't know if somehow PySide2/PyQt requires you to explicitly define your own __init__() and call the base, unless you have some reference for that?

                        jeremy_kJ 1 Reply Last reply
                        1
                        • JonBJ JonB

                          @jeremy_k
                          Well, in Python just like in, say, C++, if you do not define your own __init__() (constructor in C++) the language will always cause the base class's __init__()/constructor. If you do define your own, you must then explicitly call the base class __init__()/constructor, in either language. in Python.

                          [EDIT As @jeremy_k pointed out below, I was wrong to say this applies in all C++ cases. Let's leave it as: in Python, if you define any derived __init__() you must (should) explicitly call the base __init__() from there; but if you do not define a derived __init__() the base one will still be called.]

                          I vaguely recall reports of misbehavior using PyQt if a Qt object's constructor isn't invoked

                          I don't know if somehow PySide2/PyQt requires you to explicitly define your own __init__() and call the base, unless you have some reference for that?

                          jeremy_kJ Offline
                          jeremy_kJ Offline
                          jeremy_k
                          wrote on last edited by
                          #13

                          @JonB said in QGestureRecognizer.registerRecognizer() crashes using PySide2:

                          @jeremy_k
                          Well, in Python just like in, say, C++, if you do not define your own __init__() (constructor in C++) the language will always cause the base class's __init__()/constructor. If you do define your own, you must then explicitly call the base class __init__()/constructor, in either language.

                          That's inaccurate for C++ base class default constructors. The compiler will insert a call to the base constructor if the programmer does not. Explicit invocation is only required if there are arguments to pass.

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

                          JonBJ 1 Reply Last reply
                          1
                          • jeremy_kJ jeremy_k

                            @JonB said in QGestureRecognizer.registerRecognizer() crashes using PySide2:

                            @jeremy_k
                            Well, in Python just like in, say, C++, if you do not define your own __init__() (constructor in C++) the language will always cause the base class's __init__()/constructor. If you do define your own, you must then explicitly call the base class __init__()/constructor, in either language.

                            That's inaccurate for C++ base class default constructors. The compiler will insert a call to the base constructor if the programmer does not. Explicit invocation is only required if there are arguments to pass.

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

                            @jeremy_k
                            You are quite correct, and thank you for pointing this out. Partly I was unconsciously thinking of constructors with parameters, and partly I make slips as I swap between C#/C++/Python/JavaScript! I will correct my previous post, so as not to mislead.

                            1 Reply Last reply
                            0
                            • SGaistS Offline
                              SGaistS Offline
                              SGaist
                              Lifetime Qt Champion
                              wrote on last edited by
                              #15

                              You may have found a bug in the PySide2 implementation. Did you check if you have the same behaviour with PySide6 ?

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

                              N 1 Reply Last reply
                              0
                              • SGaistS SGaist

                                You may have found a bug in the PySide2 implementation. Did you check if you have the same behaviour with PySide6 ?

                                N Offline
                                N Offline
                                nutrx
                                wrote on last edited by
                                #16

                                @SGaist yes, same with PySide6

                                1 Reply Last reply
                                0
                                • SGaistS Offline
                                  SGaistS Offline
                                  SGaist
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #17

                                  Then you should go to the bug report system and see if there's already something there. If not, please consider opening a new issue providing your minimal runnable script that shows that behaviour.

                                  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
                                    nutrx
                                    wrote on last edited by nutrx
                                    #18

                                    Yeah, just found a bugreport reporting this exact issue. It's open since 2015..........
                                    I am really confused. I mean ... isn't this making the whole custom gesture recognizer system completely unsuable?

                                    1 Reply Last reply
                                    0
                                    • SGaistS Offline
                                      SGaistS Offline
                                      SGaist
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #19

                                      It's an issue on Python and it has likely not been used that much with that language. You can add a comment on the issue to remind the current assigned person that this is still not solved.

                                      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

                                      • Login

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