Qt / QML - Группировка и повторное использование элементов - PullRequest
0 голосов
/ 30 сентября 2018

Может ли кто-нибудь указать мне правильное направление, как лучше организовать мой QML?

В настоящее время для общих отдельных компонентов я создаю новый файл QML и добавляю его в каталог Common в моих ресурсах.

Например, мой Label.qml

Text{
    width: parent.width * 0.5
    height: parent.height * 0.1
    color: "#ffffff"
    font.underline: true
    font.pointSize: 16
    verticalAlignment: Text.AlignBottom
    horizontalAlignment: Text.AlignLeft
}

А потом в моем Form.qml я могу импортировать и использовать его так:

   import "Common"

    Page {

        Label{
            id: username_lbl
            text: "Username"
            anchors.topMargin: parent.height * 0.1
        }

    ...
    }

Но как бы я это сделал?выше, если я хочу сгруппировать несколько компонентов и ссылаться на них для использования с соединениями?

Например, я хотел бы, чтобы пара кнопок располагалась внизу страницы ( ниже - просто пример и не работает ):

ИтакЯ хотел бы иметь ButtonPair.qml, который должен выглядеть примерно так:

    Button {
        id: left_btn
        width: parent.width * 0.5
        height: parent.height * 0.1

        anchors.bottom: parent.bottom
        anchors.right: parent.right

    }

    Button {
        id: right_btn
        width: parent.width * 0.5
        height: parent.height * 0.1

        anchors.bottom: parent.bottom
        anchors.left: parent.left
    }

А затем в моем Form.qml я хотел бы использовать эти кнопки и добавить обработчик событий для каждой:

import "Common"

Page {

    ButtonPair{id: back_forward_buttons}

    Connections {
        target: back_forward_buttons.left_btn
        onClicked: {
            stackView.pop();
    }

    Connections {
        target: back_forward_buttons.right_btn
        onClicked: {
            stackView.push("AnotherPage.qml");
    }

}

Нужно ли мне обернуть ButtonPair в Component и использовать Loader на моей странице, и если да, то как мне добраться до отдельных кнопок влево / вправо, чтобыпривязать к onClicked?

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Как правило, аппроксимация «черного ящика», принятая @eyllanesc, является лучшей и должна быть предпочтительной, когда это возможно.Однако, если вам действительно нужен доступ к дочерним элементам извне, вы можете:

ButtonPair.qml:

Item {
    property alias leftButton: left_btn
    property alias rightButton: right_btn

    // … declarations of left_btn and right_btn as in your question
}

Использование:

ButtonPair {
    leftButton {
        onClicked: {
            stackView.pop();
        }
    }
    rightButton {
        onClicked: {
            stackView.push("AnotherPage.qml");
        }
    }
}

Вы также можетеиспользуйте его в Connections.Однако в 95% случаев вы должны перенаправлять свойства и сигналы, как в подходе @ eyllanesc, что приводит к намного более чистому и читаемому интерфейсу.

0 голосов
/ 01 октября 2018

Когда компонент спроектирован, он считается черным ящиком, обладающим свойствами и сигналами, которые должны просматриваться снаружи.

Например, в вашем случае ButtonPair должна выставлять 2 сигнала: один, когда левая кнопкаи еще одна, когда нажата правая кнопка, еще одна вещь, которую я добавил, - это 2 свойства, позволяющие установить имя кнопок.

Я вижу, что вы установили высоту кнопок равной 10% от высоты отца и должно быть в нижней части, и если вы хотите использовать этот же компонент сверху?Я должен был бы создать другой компонент topButtonPair, и если я хочу, чтобы они были справа и т. Д. Размер должен быть установлен, когда компонент создается не в реализации.В этом случае каждая кнопка должна занимать половину родительского элемента.

Используя вышеизложенное, мы получаем следующее:

ButtonPair.qml

import QtQuick 2.0
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11

Item{
    // expose properties and signals
    property string leftname: ""
    property string rightname: ""
    signal leftClicked()
    signal rightClicked()

    // internals
    RowLayout{
        anchors.fill: parent
        spacing: 0
        Button {
            text: leftname
            onClicked: leftClicked()
            Layout.fillWidth: true
            Layout.fillHeight: true
        }
        Button {
            text: rightname
            onClicked: rightClicked()
            Layout.fillWidth: true
            Layout.fillHeight: true
        }
    }
}

Примечание: Использование макета не является обязательным, вы можете использовать якоря.

Теперь используется на странице:

Page {

    // other components

    ButtonPair{
        anchors.bottom: parent.bottom
        height: 0.1*parent.height // <--- Here the height is established
        anchors.left: parent.left
        anchors.right: parent.right
        leftname: "left text"
        rightname: "right text"
        onLeftClicked: console.log("left clicked")
        onRightClicked: console.log("right clicked")
    }
}
...