QML Loader doesn't change its active state

106 views Asked by At

In the following QML code:

ApplicationWindow {
    id: mainItem
    
    width: 1024
    height: 600
    
    property bool firstVal: true
    property bool secondVal: true
    property bool thirdVal: true
    
    // HOME PAGE
    Loader {
        id: homeLoader
        sourceComponent: homeComponent
        active: false
        visible: false
    }
    
    Component {
        id:homeComponent
        
        PageHome {
            id: home
            visible: true;
            
            onSgnSetFirst: { // signal sgnSetFirst(val)
                firstVal = val
            }
            
            onSgnSetSecond: { // signal sgnSetSecond(val)
                secondVal = val
            }
            
            onSgnSetThird: { // signal sgnSetThird(val)
                thirdVal = val
            }
        }
    }
    
    // FIRST PAGE
    Loader {
        id: firstLoader
        sourceComponent: firstComponent
        active: false
        visible: false
    }
    
    Component {
        id: firstComponent
        
        PageFirst {
            id:firstPage
            visible: true;
        }
    }
    
    // SECOND PAGE
    Loader {
        id: secondLoader
        sourceComponent: secondComponent
        active: false
        visible: false
    }
    
    Component {
        id: secondComponent
        
        PageSecond {
            id:secondPage
            visible: true;
        }
    }
    
    // THIRD PAGE
    Loader {
        id: thirdLoader
        sourceComponent: thirdComponent
        active: false
        visible: false
    }
    
    
    Component {
        id: thirdComponent
        
        PageThird {
            id:thirdPage
            visible: true;
        }
    }
    
    Rectangle {
        id: rectangleMain
        
        width: 1024
        height: 600
        color: "transparent"
        
        state: "rms_HOME"
        
        states: [
            State {
                name: ""
                
                PropertyChanges {target: homeLoader;     active:  false}
                PropertyChanges {target: firstLoader;    active:  false}
                PropertyChanges {target: secondLoader;   active:  false}
                PropertyChanges {target: thirdLoader;    active:  false}
                
                PropertyChanges {target: homeLoader;     visible: false}
                PropertyChanges {target: firstLoader;    visible: false}
                PropertyChanges {target: secondLoader;   visible: false}
                PropertyChanges {target: thirdLoader;    visible: false}
            },
            
            // HOME PAGE
            State {
                name: "rms_HOME"
                
                PropertyChanges {target: homeLoader;     active:  true     }
                PropertyChanges {target: firstLoader;    active:  firstVal }
                PropertyChanges {target: secondLoader;   active:  secondVal}
                PropertyChanges {target: thirdLoader;    active:  thirdVal }
                
                PropertyChanges {target: homeLoader;     visible: true }
                PropertyChanges {target: firstLoader;    visible: false}
                PropertyChanges {target: secondLoader;   visible: false}
                PropertyChanges {target: thirdLoader;    visible: false}
            },
            
            // FIRST PAGE
            State {
                name: "rms_FIRST"
                
                PropertyChanges {target: homeLoader;     active:  false}
                PropertyChanges {target: firstLoader;    active:  true }
                PropertyChanges {target: secondLoader;   active:  false}
                PropertyChanges {target: thirdLoader;    active:  false}
                
                PropertyChanges {target: homeLoader;     visible: false}
                PropertyChanges {target: firstLoader;    visible: true }
                PropertyChanges {target: secondLoader;   visible: false}
                PropertyChanges {target: thirdLoader;    visible: false}
            },
            
            // SECOND PAGE
            State {
                name: "rms_SECOND"
                
                PropertyChanges {target: homeLoader;     active:  false}
                PropertyChanges {target: firstLoader;    active:  false}
                PropertyChanges {target: secondLoader;   active:  true }
                PropertyChanges {target: thirdLoader;    active:  false}
                
                PropertyChanges {target: homeLoader;     visible: false}
                PropertyChanges {target: firstLoader;    visible: false}
                PropertyChanges {target: secondLoader;   visible: true }
                PropertyChanges {target: thirdLoader;    visible: false}
            },
            
            // THIRD PAGE
            State {
                name: "rms_THIRD"
                
                PropertyChanges {target: homeLoader;     active:  false}
                PropertyChanges {target: firstLoader;    active:  false}
                PropertyChanges {target: secondLoader;   active:  false}
                PropertyChanges {target: thirdLoader;    active:  true }
                
                PropertyChanges {target: homeLoader;     visible: false}
                PropertyChanges {target: firstLoader;    visible: false}
                PropertyChanges {target: secondLoader;   visible: false}
                PropertyChanges {target: thirdLoader;    visible: true }
            }
        ]
    }
}

There are four screens: home page, first page, second page and third page.

Each of them is managed by a Loader. Each Loader is enabled/disabled by means the state property of the rectangleMain item.

When the rectangleMain.state property is set to rms_HOME, the homeLoader is active and visible while the others Loader are not visible but can be active or not depending on the firstVal, secondVal and thirdVal.

The logic works well only if the rectangleMain.state property change from rms_FIRST or rms_SECOND or rms_THIRD to rms_HOME but it doesn't work if the rectangleMain.state property is equal to rms_HOME and firstVal or secondVal or thirdVal change its value.

Why? How can I solve this problem?

1

There are 1 answers

3
Xic On

I´ve made an minimal implementation for you. It uses the loaders in a usefull way and achievs what you want from what i can tell. Here you go:

    import QtQuick 2.0

ApplicationWindow
{
  
    //because your example is not working i am trying to implement it like this...
    //I`ve been testing it with rectangles and it works.
    //From what I see you can achieve your goal if you do it like follows:

    id: root

    width: 1024
    height: 600

    property string currentPage: "home"
  
    // use one loader to load the current component that you need, dont use multiple ones
    Loader
    {
        id:pageLoader
        
        active: true
        visible: true
        
        // here we switch the source of the loader depending on root.currentPage
        sourceComponent: {
            switch(root.currentPage) {
              case "home":
                return homeComponent
              case "firstVal":
                return firstComponent
              case "secondVal":
                return secondComponent
              case "thirdVal"
                return thirdComponent
              default: return homeComponent
            }
        }
    }

    Component
    {
        id:homeComponent

        PageHome
        {
            id:home
            visible: true;
          
            //here we now change the root.currentPage to tell the loader what to load.
            //it would be nicer to use enums here but I dont want to make it too complicated.
            
           anchors.fill: parent

        //here we now change the root.currentPage to tell the loader what to load.
        //it would be nicer to use enums here.
        
        onSgnSetFirst:  // signal sgnSetFirst(val)
        {
          root.currentPage = "firstVal";
        }

        onSgnSetSecond: // signal sgnSetSecond(val)
        {
          root.currentPage = "secondVal";
        }

        onSgnSetThird:  // signal sgnSetThird(val)
        {
          root.currentPage = "thirdVal";
        }
    }
    

    Component
    {
        id:firstComponent

        PageFirst
        {
            id:firstPage
            visible: true;
        }
    }

    Component
    {
        id:secondComponent

        PageSecond
        {
            id:secondPage
            visible: true;
        }
    }
          
    Component
    {
        id:thirdComponent

        PageThird
        {
            id:thirdPage
            visible: true;
        }
    }
}