Панель навигации QML не изменяет размер

:) В настоящее время я читаю книгу «Сквозная разработка графического интерфейса с 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) постоянно меняются. Но моя панель навигации не расширяется в любом случае. Почему это происходит?

Я не очень понимаю этот подход, но родителем NavigationButton является Column, хотя неясно, что вы пытались здесь сделать. Я бы рекомендовал использовать декларативный подход, чтобы избежать такого поведения, пока вы используете QML.

folibis 24.12.2022 16:18
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Таким образом, есть несколько проблем с вашим дизайном.

  1. Вы не должны привязываться ко всем четырем сторонам top, left, right и bottom и ожидать, что установка width повлияет на width полностью закрепленного элемента. Это относится к корневому объекту в NavigationBar.qml.
  2. В обработчике сигнала 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. Теперь он работает нормально. :)

Hubertius 25.12.2022 11:01

Одна вещь о том, что мне любопытно. Почему этот «корневой» элемент в моем коде не может быть «Элементом» NavigationBar? Я имею в виду, что я сделал это прямо сейчас с вашими советами, но я применил все к «корню» как к элементу, а не к окну MasterView, и это также отлично работает.

Hubertius 25.12.2022 11:20

Я предполагал, что корневой идентификатор установлен в элементе NavigationBar. Как правило, если вам нужно получить доступ/изменить свойства элементов, используйте идентификаторы для ссылки на них. Это упростит копирование вещей, не меняя ничего, а также упростит понимание того, откуда берутся свойства.

iam_peter 25.12.2022 11:41

Я не говорил об окне, я имел в виду Item из NavigationBar. Я отредактировал ответ.

iam_peter 25.12.2022 11:48

Другие вопросы по теме