Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-2870

QStateMachine.postEvent causes a crash if the python event object isn't kept alive

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3: Somewhat important P3: Somewhat important
    • 6.8.0, 6.7.3
    • 6.7.2
    • PySide
    • None
    • c0abb71b2 (dev), 2fda2cc5e (6.7), c743c4407 (6.7.3)

      Just writing something like

      class MyClass(QObject):
          def __init__(self, parent):
              self.machine = QStateMachine(self)
      ...
          @Slot()
          def some_handler(self):
              self.machine.postEvent(QEvent(QEvent.Type.User))
      

      will cause a hard crash shortly after the state machine finishes processing the event.

      If you keep the Python reference to the QEvent alive at least long enough for the machine to process it then the crash can be avoided, e.g. writing something like

          @Slot()
          def some_handler(self):
              self.last_event = QEvent(QEvent.Type.User)
              self.machine.postEvent(self.last_event)
      

      is sufficient to prevent the crash though I imagine it might not work if multiple calls to some_handler occurred during the same tick of the event loop.

      The root cause seems to be QStateMachine.postEvent() not taking ownership of the event object despite that appearing to be the correct behaviour per the documentation.

      I can demonstrate this by contrasting it with QCoreApplication.postEvent which has similar phrasing around ownership in the docs, e.g.

              e1 = QEvent(QEvent.Type.User)
              print(f"Created event 1, owned by python? {Shiboken.ownedByPython(e1)}")
              QCoreApplication.postEvent(self.machine, e1)
              print(f"Posted event 1, owned by python? {Shiboken.ownedByPython(e1)}")
      
              e2 = QEvent(QEvent.Type.User)
              print(f"Created event 2, owned by python? {Shiboken.ownedByPython(e2)}")
              self.machine.postEvent(e2)
              print(f"Posted event 2, owned by python? {Shiboken.ownedByPython(e2)}")
      

      Produces the output:

      Created event 1, owned by python? True
      Posted event 1, owned by python? False
      Created event 2, owned by python? True
      Posted event 2, owned by python? True
      

      I think the fix might be a change to the shiboken configuration files for QStateMachine but I wasn't able to get a local build of PySide6 working on my machine to test that theory.

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            kleint Friedemann Kleint
            duncan.mackintosh Duncan Mackintosh
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes