PySide6 registering to QScxmlStateMachine event failure

102 views Asked by At

PySide on Python 3.10.5

PySide6.__version_info__ = (6, 3, 0, '', '')

Using QScxmlStateMachine connectToEvent(), method I always get the message:

qt.core.qobject.connect: QObject::connect: No such slot ...

The error happens when the slot has an argument of type QScxmlEvent. No error when no argument in the slot but such slot is not useful. The C++ code can use many overriden connectToEvent signatures, PySide only has one of them and it resembles the old signal-slot way, using the SLOT macro.

The code is:

from PySide6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QLabel
from PySide6.QtCore import SLOT, Slot, Qt
from PySide6.QtScxml import QScxmlStateMachine, QScxmlEvent


class MainWindow(QWidget):
    def __init__(self, scxml_file_name: str) -> None:
        super().__init__()

        self.machine = QScxmlStateMachine.fromFile(scxml_file_name)
        if self.machine.parseErrors():
            raise Exception()
        self.machine.start()

        layout = QVBoxLayout(self)

        self.label = QLabel(self)
        self.label.setAlignment(Qt.AlignCenter)
        layout.addWidget(self.label, 0)

        to_local = QPushButton('To Local', self)
        to_local.clicked.connect(lambda: self.machine.submitEvent('to_local'))
        layout.addWidget(to_local, 0)

        to_global = QPushButton('To Global', self)
        to_global.clicked.connect(lambda: self.machine.submitEvent('to_global'))
        layout.addWidget(to_global, 0)

        to_quit = QPushButton('To Out', self)
        to_quit.clicked.connect(lambda: self.machine.submitEvent('to_out'))
        layout.addWidget(to_quit, 0)

        exit = QPushButton('Quit', self)
        exit.clicked.connect(self.close)
        layout.addWidget(exit, 0)

        self.setLayout(layout)

        self.machine.connectToEvent('exiting', self, SLOT('on_exiting(QScxmlEvent)'))

        self.machine.reachedStableState.connect(lambda: self.label.setText(
            ', '.join(self.machine.activeStateNames()))
        )

    @Slot(QScxmlEvent)
    def on_exiting(self, event: QScxmlEvent):
        print(event)

if __name__ == '__main__':
    app = QApplication()
    win = MainWindow('statechart.scxml')
    win.show()
    app.exec()

The statechart is:

<?xml version="1.0" ?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" name="Statechart" initial="global">
    <state id="global">
        <transition event="to_local" target="local"/>
    </state>
    <state id="local">
        <transition event="to_global" target="global"/>
        <transition event="to_out" target="quit">
            <send event="exiting">
                <param name="state" expr="local"/>
            </send>
        </transition>
    </state>
    <final id="quit" />
</scxml>

I just can't figure out why the connection fails.

0

There are 0 answers