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. QStateMachine QML / enums
Forum Updated to NodeBB v4.3 + New Features

QStateMachine QML / enums

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
1 Posts 1 Posters 356 Views 1 Watching
  • 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.
  • enelE Offline
    enelE Offline
    enel
    wrote on last edited by enel
    #1

    Following this example, I am trying to use a C++ QStateMachine in QML, exposing the current state as property:
    My property is an enum, as I need to use many more states in the real application.

    class Application : public QObject  {   
    public:
        Q_OBJECT
        //QML_ELEMENT           // prevents from using the State in when clause of QML states at all
        QML_NAMED_ELEMENT(App)  // ok, but emits an error in QML
    
        enum State { OFF, ON, };  // using enum class doesn't make a difference
        Q_ENUM(State)
        
        Q_PROPERTY(Application::State state READ state NOTIFY stateChanged)
    
    Application()  {
        auto offState = new QState(&m_stateMachine);
        offState->assignProperty(&m_stateMachine, g_state_id, State::OFF);
        QObject::connect(offState, &QState::entered, this, &Application::setState);
    
        auto onState = new QState(&m_stateMachine);
        onState->assignProperty(&m_stateMachine, g_state_id, State::ON);
        QObject::connect(onState, &QState::entered, this, &Application::setState);
    
        offState->addTransition(this, &Application::toggle, onState);
        onState->addTransition(this, &Application::toggle, offState);
    
        m_stateMachine.setInitialState(offState);
        m_stateMachine.start();
    }
    
    Application::State state() const {
        return static_cast<Application::State> (m_stateMachine.property("state").toInt());
    }
    bool isState(Application::State theState) const {
        return state() == theState;
    }
    
    signals:
       void stateChanged();
       void toggle();
    
    private:
        QStateMachine m_stateMachine;
        State m_state;
        
        void Application::setState() {
           if (state() == m_state) return;    
           m_state = state();    
           emit stateChanged(); 
        }
    };    
    

    In my RowLayout element, I want to use the state like so:

    // ... inside some RowLayout target onOffBtn is a simple Button
    states : [
        State {
        	name: "off"
        	//when: app.state === 0               // Ok
            //when: app.isState(App.OFF)     // not working at all (0 in all cases)
        	when: app.state === App.OFF   // TypeError: Cannot read property 'state' of null
        	PropertyChanges { target: onOffBtn; text: "turn ON"; }
        },
        State {
        	name: "on"
        	//when: app.state === 1               // Ok
        	//when: app.isState(App.ON)       // not working at all   	when: app.state === App.ON
        	PropertyChanges { target: onOffBtn; text: "turn OFF"; }
        }
    ]
    

    Using the enum state from the registered type App, I get an error about the property state being null. But the code is working, the when part is evaluated correctly.
    Using the enum in another context (QML Button), like

    onClicked : {
         if (app.isState(App.OFF))
              console.log("app.isState(App.OFF)")
         else if (app.isState(App.ON))
              console.log("app.isState(App.ON)")
    
         if (app.state === App.OFF)
              console.log("app.state === App.OFF")
         else if (app.state === App.ON)
              console.log("app.state === App.ON")
    }
    

    onClicked produces the expected outputs without errors or warnings.

    I expected a much better way coupling the C++ SM with QML, one without using enums to react on the current state in QML (not using the QML StateMachine type).

    Am I using the states / property binding the wrong way? What is the suggested way to handle the current C++ SM state in QML?

    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