Solved 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.