Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

State Transition vs StateMachine onEntered/onExited



  • Can anyone help me out with the clear explanation(and/or example) when using state transition vs Statemachine onEntered/onExited event.

    in my design, I have a Rectange (afTemplate) inside there are 3 items (homeScreenContainer, listScreenContainer and artScreenContainer), inside each items there are different components. (like image, list, rectangle, buttons, etc) I need to move around with the items based upon the states which depends on the external value which changes at 25-75mSec interval.

    I'm facing multiple issue,

    1. where I do lot of Property changes when getting into an 'State', but I noticed a delay and order at which the properties gets changed also varies time to time. What is the latency between the moment I enter the state and changing the properties. When exactly the 'Transition' happens? During Entering the State or Exiting a State.

    Code Snippet:

    states [
    State {
      name: "phonelistScreen"
      when: ((afTemplate.m_menu_state === 6) && (m_home_scr_idx === 1))
      PropertyChanges { target: listScreenContainer; visible: true;}
      PropertyChanges { target: compassUi;visible: false;}
      PropertyChanges { target: homeScreenContainer; visible: false; }
      PropertyChanges { target: artScreenContainer; visible: false; }
      PropertyChanges { target: bgImg; source: "pics/phone_panel_bg_img.png"; }
      PropertyChanges { target: afTemplate; m_heading_txt: m_phone_src ? "Recent Calls" : "Contacts"; m_send_screen_id: 1; m_phonelist: m_contactlist;m_prevlistIdx:1; m_play_songs: m_play_songs ? true : false;}
      PropertyChanges { target: listLayout; p_showImg:m_phone_src; pObjName:m_phonelist; p_listCount:m_phonelist.count; p_listCurrentIdx: m_contact_index; p_UpButnState: 0; p_DwnButnState: 0;}
    },
    State {
      name: "msglistScreen"
      when: (((afTemplate.m_menu_state === 7) || (afTemplate.m_menu_state === 9)) && (m_home_scr_idx === 1))
      PropertyChanges { target: compassUi;visible: false;}
      PropertyChanges { target: bgImg; source: "pics/phone_panel_bg_img.png"; }
      PropertyChanges { target: homeScreenContainer; visible: false; }
      PropertyChanges { target: artScreenContainer; visible: false; }
      PropertyChanges { target: afTemplate; m_heading_txt: "Choose Message to Send"; m_send_screen_id: 1; m_phonelist: m_msglist;m_prevlistIdx:1;m_play_songs : m_play_songs ? true : false; }
      PropertyChanges { target: listLayout; pObjName:m_phonelist; p_listCount:m_phonelist.count; p_listCurrentIdx: 0;p_UpButnState: 0; p_DwnButnState: 0;}
      PropertyChanges { target: listScreenContainer; visible: true; }
    },
    State {
      name: "incomingCallAlertScreen"
      when: ((afTemplate.m_menu_state === 8) && (m_home_scr_idx === 1))
      PropertyChanges { target: bgImg; source: "pics/phone_panel_bg_img.png"; }
      PropertyChanges { target: afTemplate; m_heading_txt: "Incoming Call..."; m_send_screen_id: 2;m_play_songs: m_play_songs ? true : false; m_updateToPhone:true;}
      PropertyChanges { target: listScreenContainer; visible: false; }
      PropertyChanges { target: artAlbumName; visible: false; }
      PropertyChanges { target: artArtistName; visible: false; }
      PropertyChanges { target: homeScreenContainer; visible: false; }
      PropertyChanges { target: artHeadingTxt; visible: true; }
      PropertyChanges { target: artScreenContainer; visible: true; }
    },
    State {
       name: "callConnectedScree"
       when: ((afTemplate.m_menu_state === 10) && (m_home_scr_idx === 1))
        PropertyChanges { target: bgImg; source: "pics/phone_panel_bg_img.png"; }
        PropertyChanges { target: afTemplate; m_heading_txt: "Active Call"; m_send_screen_id: 2;m_play_songs: m_play_songs ? true : false; m_updateToPhone:true;}        
        PropertyChanges { target: listScreenContainer; visible: false; }        
        PropertyChanges { target: artArtistName; visible: false; }        
        PropertyChanges { target: artAlbumName; visible: false; }
        PropertyChanges { target: homeScreenContainer; visible: false; }        
        PropertyChanges { target: artHeadingTxt; visible: true; }        
        PropertyChanges { target: artScreenContainer; visible: true; }        
    },
    State {
      name: "msgSendingScreen"
      when: ((afTemplate.m_menu_state === 11) && (m_home_scr_idx === 1))
      PropertyChanges { target: artScreenContainer; visible: true; }        
      PropertyChanges { target: msgTimer; running: true; }        
      PropertyChanges { target: bgImg; source: "pics/phone_panel_bg_img.png"; }        
      PropertyChanges { target: listScreenContainer; visible: false; }        
      PropertyChanges { target: afTemplate; m_heading_txt: "Sending Message"; m_send_screen_id: 2;m_play_songs: m_play_songs ? true : false; m_updateToPhone:true;}        
      PropertyChanges { target: artAlbumName; visible: false; }        
      PropertyChanges { target: artArtistName; visible: false; }        
      PropertyChanges { target: artHeadingTxt; anchors.verticalCenterOffset: 50; }
      PropertyChanges { target: artImg; anchors.verticalCenterOffset: 50; }
      PropertyChanges { target: homeScreenContainer; visible: false; }
      PropertyChanges { target: artHeadingTxt; visible: true; }
     }
    ]
    
    1. what happens when there is an external event (for example a variant value changes) changes a state when I'm already inside a state?

    2. Is there a way I can change some properties while exiting from a state using general 'State' or I should go with StateMachine concept and use onExited. In that case what causes onExited to trigger?

    3. Will using StateChangeScript instead of multiple PropertyChanges gives any advantages w.r.t execution time.

    4. Will there be any possibilities that that I may enter into unknown state or state looping within itself and crash at sometime.

    I found some documentation like the below, will this be an issue for my crash.
    State Fast Forwarding
    In order for Transition to correctly animate state changes, it is sometimes necessary for the engine to fast forward and rewind a state (that is, internally set and unset the state) before it is finally applied. The process is as follows:

    The state is fast forwarded to determine the complete set of end values.
    The state is rewound.
    The state is fully applied, with transitions.
    In some cases this may cause unintended behavior. For example, a state that changes a view's model or a Loader's sourceComponent will set these properties multiple times (to apply, rewind, and then reapply), which can be relatively expensive.

    State fast forwarding should be considered an implementation detail, and may change in later versions.

    CRASH: happens when I'm inside a(ny) state where non of the 3 Containers are visible.
    I get crash at the following function, but my QML has already received the signal. Note: This signal is sent from the backend multiple times say for example every 100mSec interval
    File: moc_buttonbackend.cpp

    void ButtonBackend::funcButtonChanged(int _t1, int _t2)
    {
        void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t1))), const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t2))) };
        QMetaObject::activate(this, &staticMetaObject, 0, _a);
    }
    

    Error1.PNG

    qml: LayoutTemplate : recv_func_butn_state index :  0 ,state :  1 STATE :  callConnectedScreen , af_fun_butn.model :  1
    qml: LayoutTemplate : recv_func_butn_state :  Active Call Menu Screen : m_home_scr_idx :  1 ,m_menu_scr_idx :  -1 , m_menu_state :  10
    qml: ENTER : onM_func_scr_idxChanged :  Active Call Menu Screen : m_home_scr_idx :  1 ,m_func_scr_idx :  0 , m_menu_state :  10
    qml: ENTER : 00000 onM_func_scr_idxChanged :  Active Call Menu Screen : p_listCurrentIdx :  9 ,m_contact_index :  9
    Critical error detected c0000374
    

    I highly appreciate your help.!


Log in to reply