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

Switching between different views and anchoring them properly w.r.t parent.



  • My application needs switching between views like upon clicking a button another view have to be shown and upon clicking back button it has to comeback to mainview. I implemented this using States and visible concept. By setting the visible property to false.
    please see the pics to understand my problem.

    Main.qml
    ControlRegisterView.qml
    AcyclicRegView.qml

    Problem:
    Even though i made DisplayView.qml as invisible but it is **cliping **the text writen in present view. It seems obvious that there is something hidden which i dont want to show.

    Main.qml

    import QtQuick 2.3
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.3
    Window{
        id:window
        width: Screen.width
        height: Screen.height
        visible: true
        Item{ 
            id:mainUI
            anchors.fill: parent
    
            Header{
                id:header
            }
            CentralView{
                id:centralView
                anchors.top: header.bottom
                anchors.bottom: footer.top
            }
            Footer {
                id: footer
                anchors.bottom: parent.bottom
            }
            states: [
                State {
                    name: "MainView"
                    PropertyChanges {target: centralView;cycRegVisible:false; ctrlReg1Visible:false;
                    PropertyChanges {target: footer;backButtonvisible:false; }
                },
                State {
                    name: "CyclicRegisterView"
                    PropertyChanges {target: centralView;cycRegVisible:true }
                    PropertyChanges {target: footer;backButtonvisible:true}
                    PropertyChanges {target: centralView;displayViewVisible:false }
                },
                State {
                    name: "ControlRegister1View"
                    PropertyChanges {target: centralView;cycRegVisible:false;ctrlReg1Visible:true;
                    PropertyChanges {target: footer;backButtonvisible:true; }
                    PropertyChanges {target: centralView;**displayViewVisible**:false }
                },
            ]
            state: "MainView"
            Connections{
                target: centralView;
                onAcyclicButtonClicked:{
                    console.log("switching to CyclicRegisterView")
                    mainUI.state="CyclicRegisterView"
                }
                onControlRegister1ButtonClicked:{
                    console.log("switching to Control Register1View")
                    mainUI.state="ControlRegister1View"
                }
            }
            Connections{
                target: footer
                onBackButtoncliked:{
                    console.log("switching to MainView")
                    mainUI.state="MainView"
                }
            }
        }
    

    CentralView.qml consists of half display view and half control view .

    Item {
        id:centralView
        width: parent.width
        height: parent.height
        anchors.left: parent.left
            DisplayView{
                   id: displayView
                   height: centralView.height
                   width: centralView.width/2
                   anchors.left: controlview.right
                   anchors.leftMargin: festodesign.buttonGap
                   anchors.top: sendSingleButton.bottom
                Connections{
                onAcyclicButtonClicked: {dis_acyclicButtonClicked()}
                onControlRegister1Clicked:{dis_controlRegister1ButtonClicked()}
            }
        }
        ControlView{
                  id:controlview
                 height: centralView.height
                 width: centralView.width/2
                 anchors.left: centralView.left
                 anchors.leftMargin: festodesign.buttonGap
                 anchors.top: sendSingleButton.bottom
                Connections{
                onAcyclicButtonClicked: {acyclicButtonClicked()}
                onControlRegister1Clicked:{controlRegister1ButtonClicked()}
            }
        }
    

    ControlView.qml

    Item{
    //    width: parent.width
    //    height: parent.height
    //    anchors.fill: parent
        signal acyclicButtonClicked()
        signal controlRegister1Clicked()
        property alias cycRegVisible: cyclicRegister.visible
        property alias ctrlReg1Visible: controlRegister1.visible
    
        Flickable{
            id:flickArea
    //        anchors.fill: parent
            width: parent.width
            height: parent.height
            contentHeight: parent.height*2
            contentWidth: parent.width
            flickableDirection: Flickable.VerticalFlick
            interactive: true
            clip: true
            Rectangle {
                id: controlView
                height: parent.height
                width: parent.width
                border.color: "green"
         AcyclicRegister{
                    id:cyclicRegister
                    visible: false
                    anchors.fill: parent
                    width: parent.width
                    height: parent.height
                }
                ControlRegister1{
                    id:controlRegister1
                    visible: false
    //                width: parent.width
                    height: parent.height
                    width: Screen.width
                }
           }
        }
     }
    

    ControlRegister1.qml

    import QtQuick 2.0
    
    Item {
        id: controlRegisteritem
    
    //    z:1
        anchors.fill: parent
    //    width: Screen.width
        Register{
            id:controlRegister
            setTitle: "Control Register-1"
            anchors.fill: parent
            setBit1Caption: "EMSTOP"
            setBit1Description: qsTr("Emergency Stop:.....
          }
    }
    

    Register.qml

    Rectangle {
        id: register
    //    width: Screen.width-10
    //    height: parent.height
        anchors.fill: parent
    }
    

    DisplayView.qml looks same as controlview.qml just text is different.

    I have removed all the unnecessary code.Sorry for the long description.If you didn't understand my problem.
    Do you guys have an example where i can switching between views and the views should fill the whole screen apart from header and footer? Thanks


  • Moderators

    Hi @vishnucool220,
    I think its better to use a StackView here. Add those individual QML as pages for StackView. Then you can just push and pop them for switching. StackView provides transitions too so that you don't need to maintain states.
    For the header and footer part use ApplicationWindow. The content area would contain your StackView.

    P.S : Please surround your code with ``` (3 backticks) so that its more readable. I have done it for you now.


  • Moderators

    @vishnucool220
    I'll answer it here. Following are the 2 things which are clipping the Text:

    • I found that the ControlView.qml holds the Flickable which then loads the ControlRegister1 which contains the text which is getting clipped.
      The problem here is that the Flickable gets its width and height from its parent i.e ControlView.qml and thus loading ControlRegister1 inside Flickable will get clipped simply because its holder i.e Flickable is not wide enough.
    • You have explicitly set clip to true. But setting it false will make it overlap on header when scrolled.

    I think you should seriously consider redesigning your application now itself to avoid further complications. Another issue that I found is the inclusion of Buttons, Text, TextInput etc.. in the header. You have just anchored them to one another and keeping the width fixed. This will tear apart when the resolution changes. Instead consider using RowLayout.



  • Hey!
    Thanks a lot for reviewing my code. I understood the problem but I didn't understand how to solve it. Can you propose any example or modification to my code? Ofcourse you already proposed StackView but still without using that.Thanks


  • Moderators

    @vishnucool220
    One quick suggestion that I could think of is not to load ControlRegister1 inside Flickable. Instead load it using Loader and let this Loader be in CentralView.qml. Set its width and height to that of its parent Item which fills the screen (as seen in the code). Thus when you load ControlRegister1 it will occupy the whole width and not clip the text.
    Also make sure you hide DisplayView and ControlView when you load ControlRegister1 inside the Loader.



  • @p3c0
    Thanks !!! Text clipping problem is solved by using loader in CentralView. But i lost the connection between the ControlRegister1Status and controlRegister1.How do i make connection between them? ControlRegister1Status is in ControlView and controlRegister1 is in Centralview in a Loader.How to access the alias properties of controlRegister1 and set those properties to ControlRegister1Status ?Help me please.


  • Moderators

    @vishnucool220
    The component loaded by the Loader can be accessed by item property. Once you get access to that component you can access its properties. For eg:

    Loader {
      id: loader
      sourceComponent: myComponent
    }
    ...
    
    //accessing
    loader.item.myproperty //get access to myproperty of myComponent
    

  • Moderators

    @vishnucool220 A little bit on explanation would be helpful alongside just downvoting.