Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Using Declarative State Machine with Custom C++ QML types
Forum Updated to NodeBB v4.3 + New Features

Using Declarative State Machine with Custom C++ QML types

Scheduled Pinned Locked Moved Solved QML and Qt Quick
3 Posts 1 Posters 964 Views
  • 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.
  • G Offline
    G Offline
    GRAlves
    wrote on last edited by
    #1

    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?

    G 1 Reply Last reply
    0
    • G GRAlves

      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?

      G Offline
      G Offline
      GRAlves
      wrote on last edited by GRAlves
      #2

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

      1 Reply Last reply
      0
      • G Offline
        G Offline
        GRAlves
        wrote on last edited by
        #3

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

        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