Home > Enterprise >  QML Navigation Bar isn't resizing
QML Navigation Bar isn't resizing

Time:12-25

:) I'm currently reading book "End to End GUI Development with Qt5". To gain more knowledge how is everything is working I'm executing code from book with small changes done by me. Back to the point. Currently I have a problem with resizing of navigation bar when user is clicking toggle button (first button at navigation bar) at the top of navigation bar. *Window after running aplication

Starting view is done with usage of "MasterView.qml" file:

import QtQuick
import QtQuick.Window 2.15
import QtQuick.Controls 2.2
import assets 1.0
import components 1.0

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Client Management")

    NavigationBar {
        id: navigationBar
    }

    Connections {
        target: masterController.ui_navigationController
        onGoCreateClientView: contentFrame.replace("qrc:/views/CreateClientView.qml")
        onGoDashboardView:    contentFrame.replace("qrc:/views/DashboardView.qml")
        onGoEditClientView:   contentFrame.replace("qrc:/views/EditClientView.qml", {selectedClient: client})
        onGoFindClientView:   contentFrame.replace("qrc:/views/FindClientView.qml")
    }

    StackView {
        id: contentFrame
        anchors {
            top: parent.top
            bottom: parent.bottom
            left: navigationBar.right
            right: parent.right
        }
        clip: true
    }

    Component.onCompleted: contentFrame.replace("qrc:/views/DashboardView.qml");
}

Content of NavigationBar.qml component:

import QtQuick
import QtQuick.Controls 2.2
import assets 1.0

Item {
    property bool isCollapsed: true
    property color hoverColour: Style.colourNavigationBarBackground
    anchors {
        top: parent.top
        bottom: parent.bottom
        left: parent.left
        right: contentFrame.left
    }
    width: Style.widthNavigationBarCollapsed

    Rectangle {
        id: background
        anchors.fill: parent
        color: Style.colourNavigationBarBackground
        Column {
            NavigationButton {
                iconCharacter: "\uf0c9"
                description: ""
                hoverColour: "#993333"
                onNavigationButtonClicked: {
                    isCollapsed = !isCollapsed
                    console.log("Dashboard toggle")
                    console.log("Value of collapsed: "   isCollapsed)
                    if(isCollapsed) {
                        parent.width = Style.widthNavigationBarCollapsed
                    } else {
                        console.log("Width value before: "   parent.width)
                        parent.width  = Style.heightNavigationBarExpanded
                        console.log("Style heightNavigationBarExpanded "   Style.heightNavigationBarExpanded)
                        console.log("Width value after: "   parent.width)
                    }
                        console.log("Item Background width "   parent.width)
                }
            }
            NavigationButton {
                iconCharacter: "\uf015"
                description: "Dashboard"
                hoverColour: "#993333"
            }
            NavigationButton {
                iconCharacter: "\uf234"
                description: "New Client"
                hoverColour: "#993333"
            }
            NavigationButton {
                iconCharacter: "\uf002"
                description: "Find Client"
                hoverColour: "#993333"
            }
        }

        states: [
            State {
                name: "hover"
                PropertyChanges {
                    target: background
                    color: hoverColour
                }
            }

        ]

    }

}

With NavigationButton component having code like this:

import QtQuick
import QtQuick.Controls 2.2
import assets 1.0
Item  {
    property alias iconCharacter: textIcon.text
    property alias description: textDescription.text
    property color hoverColour: Style.colourNavigationBarBackground
    signal navigationButtonClicked()

    width: Style.widthNavigationButton
    height: Style.heightNavigationButton

    Rectangle {
        id: background
        anchors.fill: parent
        color: Style.colourNavigationBarBackground
        Row {
            Text {
                id: textIcon
                width: Style.widthNavigationButtonIcon
                height: Style.heightNavigationButtonIcon
                font {
                    family: Style.fontAwesome
                    pixelSize: Style.pixelSizeNavigationBarIcon
                }
                color: Style.colourNavigationBarFont
                text: "\uf0c9"
            }
            Text {
                id: textDescription
                width: Style.widthNavigationButtonDescription
                height: Style.heightNavigationButtonDescription
                color: Style.colourNavigationBarFont
                text: ""
            }
        }
        MouseArea {
            anchors.fill: parent
            cursorShape: Qt.PointingHandCursor
            hoverEnabled: true
            onEntered: background.state = "hover"
            onExited: background.state = ""
            onClicked: navigationButtonClicked()
        }
    }
}

Color and size properties are placed in another file "Style.qml":

pragma Singleton
import QtQuick 2.9

Item {
    property alias fontAwesome: fontAwesomeLoader.name
    readonly property color colourBackground: "#efefef"
    readonly property color colourNavigationBarBackground: "#000000"
    readonly property color colourNavigationBarFont: "#ffffff"
    readonly property int pixelSizeNavigationBarIcon: 42
    readonly property real widthNavigationButtonIcon: 80
    readonly property real heightNavigationButtonIcon: widthNavigationButtonIcon
    readonly property real widthNavigationButtonDescription: 240
    readonly property real heightNavigationButtonDescription: heightNavigationButtonIcon
    readonly property real widthNavigationButton: widthNavigationButtonIcon   widthNavigationButtonDescription
    readonly property real heightNavigationButton: Math.max(heightNavigationButtonIcon, heightNavigationButtonDescription)

    readonly property real widthNavigationBarCollapsed: widthNavigationButtonIcon
    readonly property real heightNavigationBarExpanded: 320
    FontLoader {
        id: fontAwesomeLoader
        source: "qrc:/assets/fontawesome.ttf"
    }
}

As I wrote earlier, there is problem erupting after clicking navigation button. The main purpose of it is to collapse / expand navigation bar (from width of 80 to 320).

onNavigationButtonClicked: {
                    isCollapsed = !isCollapsed
                    console.log("Dashboard toggle")
                    console.log("Value of collapsed: "   isCollapsed)
                    if(isCollapsed) {
                        parent.width = Style.widthNavigationBarCollapsed
                    } else {
                        console.log("Width value before: "   parent.width)
                        parent.width  = Style.heightNavigationBarExpanded
                        console.log("Style heightNavigationBarExpanded "   Style.heightNavigationBarExpanded)
                        console.log("Width value after: "   parent.width)
                    }
                        console.log("Item Background width "   parent.width)
                }

But... nothing is happening. Even tho in console I can see that when I click that first button values of parent.width (in that case of Item) are constantly changing. But my navigation bar isn't expanding in any case. Why is that happening?

CodePudding user response:

So there are multiple issues with your design.

  1. You shouldn't anchor to all four sides top, left, right and bottom and expect setting width would impact the width of the fully anchored item. This is the case for the root object in NavigationBar.qml.
  2. In your onNavigationButtonClicked signal handler you set the parent.width to expand the navigation bar, but what you actually want to set the width of is the root item of NavigationBar. So what you need to do is to add an id to the root item Item of NavigationBar, e.g. id: root and in the signal handler set root.width = 320 and root.width = 80.

Here is a quick demo

import QtQuick
import QtQuick.Window
import QtQuick.Controls

Window {
    id: root
    width: 640
    height: 480
    visible: true
    title: qsTr("Client Management")

    property int btnWidth: 80
    property int btnHeight: 80

    component NavigationButton : Rectangle {
        id: navigationButton

        property alias icon: text.text

        signal clicked

        width: root.btnWidth
        height: root.btnHeight
        border {
            color: "black"
            width: 1
        }

        Text {
            id: text
            anchors.centerIn: parent
            font.pixelSize: 32
        }

        MouseArea {
            id: mouseArea
            anchors.fill: parent
            hoverEnabled: true
            onClicked: navigationButton.clicked()
        }

        states: [
            State {
                name: "idle"
                when: !mouseArea.containsMouse
                PropertyChanges {
                    target: navigationButton
                    color: "red"
                }
            },
            State {
                name: "hover"
                when: mouseArea.containsMouse
                PropertyChanges {
                    target: navigationButton
                    color: "blue"
                }
            }
        ]
    }

    component NavigationBar : Rectangle {
        id: navigationBar

        property bool expanded: false

        width: root.btnWidth
        height: root.height
        color: "gray"

        Column {

            NavigationButton {
                icon: navigationBar.expanded ? "X" : ">"
                onClicked: navigationBar.expanded = !navigationBar.expanded
            }

            Repeater {
                model: 3

                NavigationButton { icon: modelData }
            }
        }

        states: [
            State {
                name: "collapsed"
                when: !navigationBar.expanded
                PropertyChanges {
                    target: navigationBar
                    width: root.btnWidth
                }
            },
            State {
                name: "expanded"
                when: navigationBar.expanded
                PropertyChanges {
                    target: navigationBar
                    width: 320
                }
            }
        ]
    }

    NavigationBar {}
}
  • Related