:) 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.
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.
- You shouldn't anchor to all four sides
top
,left
,right
andbottom
and expect settingwidth
would impact thewidth
of the fully anchored item. This is the case for the root object inNavigationBar.qml
. - In your
onNavigationButtonClicked
signal handler you set theparent.width
to expand the navigation bar, but what you actually want to set thewidth
of is the root item ofNavigationBar
. So what you need to do is to add an id to the root itemItem
ofNavigationBar
, e.g.id: root
and in the signal handler setroot.width = 320
androot.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 {}
}