:) В настоящее время я читаю книгу «Сквозная разработка графического интерфейса с Qt5». Чтобы получить больше информации о том, как все работает, я выполняю код из книги с небольшими изменениями, внесенными мной. Вернемся к делу. В настоящее время у меня проблема с изменением размера панели навигации, когда пользователь нажимает кнопку переключения (первая кнопка на панели навигации) в верхней части панели навигации.
Начальный просмотр осуществляется с использованием файла "MasterView.qml":
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");
}
Содержимое компонента NavigationBar.qml:
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.info("Dashboard toggle")
console.info("Value of collapsed: " + isCollapsed)
if (isCollapsed) {
parent.width = Style.widthNavigationBarCollapsed
} else {
console.info("Width value before: " + parent.width)
parent.width = Style.heightNavigationBarExpanded
console.info("Style heightNavigationBarExpanded " + Style.heightNavigationBarExpanded)
console.info("Width value after: " + parent.width)
}
console.info("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
}
}
]
}
}
С компонентом NavigationButton, имеющим такой код:
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()
}
}
}
Свойства цвета и размера вынесены в другой файл "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"
}
}
Как я писал ранее, после нажатия кнопки навигации возникает проблема. Основная цель — свернуть/развернуть панель навигации (от ширины 80 до 320).
onNavigationButtonClicked: {
isCollapsed = !isCollapsed
console.info("Dashboard toggle")
console.info("Value of collapsed: " + isCollapsed)
if (isCollapsed) {
parent.width = Style.widthNavigationBarCollapsed
} else {
console.info("Width value before: " + parent.width)
parent.width = Style.heightNavigationBarExpanded
console.info("Style heightNavigationBarExpanded " + Style.heightNavigationBarExpanded)
console.info("Width value after: " + parent.width)
}
console.info("Item Background width " + parent.width)
}
Но... ничего не происходит. Даже в консоли я вижу, что когда я нажимаю эту первую кнопку, значения parent.width (в данном случае Item) постоянно меняются. Но моя панель навигации не расширяется в любом случае. Почему это происходит?
Таким образом, есть несколько проблем с вашим дизайном.
top
, left
, right
и bottom
и ожидать, что установка width
повлияет на width
полностью закрепленного элемента. Это относится к корневому объекту в NavigationBar.qml
.onNavigationButtonClicked
вы устанавливаете parent.width
для расширения панели навигации, но на самом деле вы хотите установить width
корневого элемента в NavigationBar
. Итак, что вам нужно сделать, это добавить идентификатор к корневому элементу Item
из NavigationBar
, например. id: root
и в обработчике сигнала установите root.width = 320
и root.width = 80
.Вот краткая демонстрация
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 {}
}
Большое спасибо за Ваш ответ. :) Я сделал, как вы мне сказали. Я дал идентификатор «Элементу» компонента NavigationBar. Это по-прежнему давало неожиданный для меня результат (панель навигации не расширялась, только ее кнопки «отсутствовали» после первого нажатия, после второго все вернулось в норму). Итак, я вернулся к пункту 1 и удалил anchors.right на Item. Теперь он работает нормально. :)
Одна вещь о том, что мне любопытно. Почему этот «корневой» элемент в моем коде не может быть «Элементом» NavigationBar? Я имею в виду, что я сделал это прямо сейчас с вашими советами, но я применил все к «корню» как к элементу, а не к окну MasterView, и это также отлично работает.
Я предполагал, что корневой идентификатор установлен в элементе NavigationBar. Как правило, если вам нужно получить доступ/изменить свойства элементов, используйте идентификаторы для ссылки на них. Это упростит копирование вещей, не меняя ничего, а также упростит понимание того, откуда берутся свойства.
Я не говорил об окне, я имел в виду Item
из NavigationBar
. Я отредактировал ответ.
Я не очень понимаю этот подход, но родителем
NavigationButton
являетсяColumn
, хотя неясно, что вы пытались здесь сделать. Я бы рекомендовал использовать декларативный подход, чтобы избежать такого поведения, пока вы используете QML.