Using Declarative State Machine with Custom C++ QML types



  • Hi,

    I'd like to create a custom QML type in C++ that can contain one or more state machines. My idea is to have the state machine declared on the qml file.

    So far I have created the following type:

    class TestQML : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
    public:
        explicit TestQML(QObject *parent = 0);
        QString getName() const;
        void setName(const QString &name);
    signals:
        void nameChanged();
        void Started();
    
    public slots:
        void start();
    
    private:
        QString m_name;
    };
    

    And the following qml file:

    import testbench 1.0
    import QtQml 2.0
    import QtQml.StateMachine 1.0
    
    Test {
        name: "Test 1"
    
        onTestStarted: {
            machine.running = true;
        }
    
        StateMachine {
            id:machine
            initialState: ini
            running: false
            State {
                id: ini
                SignalTransition {
                    targetState: final
                }
            }
            FinalState {
                id: final
            }
            onFinished: base.finish("OK!")
        }
    
    }
    
    
    

    Where base is an object with a finish slot that have been exposed to the engine using

        m_engine = new QQmlEngine(this);
        m_engine->rootContext()->setContextProperty("base",this);
    

    I execute the QML script by using:

            QQmlComponent component(m_engine, url);
            QObject *obj = component.create();
            TestQML *tst = qobject_cast<TestQML*>(obj);
            if (tst) {
                qDebug() << "Teste ID: "            << tst->getName();
                tst->startTest();
            }
            delete obj;
    

    I am getting the following error:

    QQmlComponent: Component is not ready
    

    If I remove the state machine the program works as expected. I isolated the problem to the "import QtQml.StateMachine 1.0" statment - if I remove it the program runs.
    I read all the documentation available on the Declarative State Machine framework but I couldn't find anything related to this particular problem. Does anyone have had similar problems importing the framework? Is there a particular Qt Module that I have to link against in order to have StateMachine working?



  • @GRAlves
    I found that I was missing the qml-module-qtqml-statemachine module on my ubuntu installation. That fixed the crash with the import statement but I still can't get the Test obejct to accept a StateMachine as a part of it. Is there some modification I need to do on the C++ class for it to accept StateMachine children?

    After some more debugging I arrived to the following qml:

    Teste {
        id: teste1
        name: "Teste 1"
    
        onTestStarted: {
            maquina.running = true;
        }
        StateMachine {
                id:maquina
                initialState: inicio
                running: false
                State {
                    id: inicio
                    SignalTransition {
                        targetState: finalizou;
                    }
                }
                FinalState {
                    id: finalizou;
                }
                onFinished: base.finish("Tudo certo!")
            }
    }
    

    It is now failing with

    QQmlComponent: Component is not ready
    (file:///.../teste1.qml:15:5: Cannot assign to non-existent default property
            StateMachine {
            ^)
    

    I am pretty sure I need to add something to the TestQML class in order to make it work but I couldn't find any documentation on how to nest a State Machine on a custom QML type.



  • I couldn't get it to work deriving from QObject. My workaround was to derive TestQML from QQuickItem instead of QObject.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.