как добавить новый компонент с другим компонентом в качестве аргумента в qml - PullRequest
0 голосов
/ 01 февраля 2019

Что я хочу сделать, это создать новый объект внутри компонента, который можно сделать с помощью компонента Component из qml, но в качестве аргумента я хочу передать другой компонент, который будет находиться в другом файле .qml.

Я собираюсь проиллюстрировать, что я пытаюсь сделать.У меня есть аккордеонный компонент панели вкладок, который я сделал: enter image description here

Когда я нажимаю на кнопку, я хочу создать новую вкладку, которая будет иметь собственное содержимое!

enter image description here

Я предоставляю код, который я использовал ниже:

import QtQuick 2.7
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.3
import QtQuick.Window 2.3

ApplicationWindow {
    visible: true
    width: 640
    height: 500
    title: qsTr("Tabbars")
    Button{
        id: button
        text: "add new tab dinamically"
        onClicked: item.createPanelItem()
        anchors.top:parent.top
        anchors.left:parent.left
        height: 20
        width: parent.width
    }
    Item{
        id:item
        //anchors.fill:parent
        anchors.top: button.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
            ScrollView{
                anchors.fill:parent
                Column {
                    id: column
                    width:item.width
                    property int currentItem: 0
                    PanelItem {
                        id:panel1
                        index:0
                        title: "Panel 1"
                        width:parent.width
                        content: Item {
                            property string title: "teste"
                            height: configContent.implicitHeight
                            width: configContent.implicitWidth
                            ColumnLayout{
                                id:configContent
                                anchors.topMargin: 10
                                anchors.bottomMargin: 10
                                anchors.fill:parent
                                TextField {
                                    id: companyNameText1
                                    placeholderText: qsTr("Company name")
                                    Layout.fillWidth: true
                                    selectByMouse: true
                                }
                                ComboBox {
                                    id: languagesComboBox1
                                    textRole: "text"
                                    objectName: "language"
                                    Layout.fillWidth: true
                                    model: ListModel {
                                        ListElement {text: QT_TR_NOOP("English"); oid: 0}
                                        ListElement {text: QT_TR_NOOP("Portuguese"); oid: 1}
                                        ListElement {text: QT_TR_NOOP("Spanish"); oid: 2}
                                        ListElement {text: QT_TR_NOOP("Italian"); oid: 3}
                                        ListElement {text: QT_TR_NOOP("French"); oid: 4}
                                        ListElement {text: QT_TR_NOOP("Portuguese(Brasil)"); oid: 5}
                                    }
                                }
                                ComboBox {
                                    id: devSndrModeComboBox1
                                    textRole: "text"
                                    objectName: "test_dev_sndr_mode"
                                    Layout.fillWidth: true
                                    model: ListModel {
                                        Component.onCompleted: {
                                            append({ text: QT_TR_NOOP("None"), oid: 0 })
                                            append({ text: QT_TR_NOOP("Subpanel"), oid: 1 })
                                            append({ text: QT_TR_NOOP("All"), oid: 2 })
                                        }
                                    }
                                }
                            }
                        }
//                        onResetOtherPanels: function(indexClicked){
//                            if()
//                        }
                    }
                    PanelItem {
                        id:panel2
                        index:1
                        title: "Panel 2"
                        width:parent.width
                        content: Item {
                            property string title: "teste"
                            height: configContent2.implicitHeight
                            width: configContent2.implicitWidth
                            ColumnLayout{
                                id:configContent2
                                anchors.fill:parent
                                ComboBox {
                                    id: sndrModeComboBox1
                                    textRole: "text"
                                    Layout.fillWidth: true
                                    model: ListModel {
                                        Component.onCompleted: {
                                            append({ text: QT_TR_NOOP("Preset"), oid: 0 })
                                            append({ text: QT_TR_NOOP("Programmed"), oid: 1 })
                                        }
                                    }
                                }
                            }
                        }
                        Component.onCompleted: {
                            //resetOtherAccordions.connect(panel1.resetHeight)
                            console.log("panel 2 height "+panel2.height)
                        }
                    }
                    PanelItem {
                        id:panel3
                        index:2
                        title: "Panel 3"
                        width:parent.width
                        content: Item {
                            property string title: "teste"
                            height: configContent3.implicitHeight
                            width: configContent3.implicitWidth
                            ColumnLayout{
                                id:configContent3
                                anchors.fill:parent
                                ComboBox {
                                    id: sndrModeComboBox2
                                    textRole: "text"
                                    Layout.fillWidth: true
                                    model: ListModel {
                                        Component.onCompleted: {
                                            append({ text: QT_TR_NOOP("Preset"), oid: 0 })
                                            append({ text: QT_TR_NOOP("Programmed"), oid: 1 })
                                        }
                                    }
                                }
                            }
                        }
                        Component.onCompleted: {
                            console.log("panel 3 height "+panel2.height)
                        }
                    }
                }
            }
            function createPanelItem(){
                panelItem.createObject(column,{title:qsTr("newTest"),index:4 /*,content: Item{}*/  })
            }
            Component {
                id: panelItem
                PanelItem {
                    title: qsTr("Teste")
                    width: parent.width
                }
            }
        }
}

PanelItem.qml:

import QtQuick 2.7
import QtQuick.Layouts 1.2

Item {
    id: root
    property Component content
    property string title: "panel"
    property bool isSelected: false
    property int index: 0
    function toggleSelected() {
        root.isSelected = !root.isSelected
        if(root.isSelected){
            parent.currentItem = index
            for(var i = 0;i<parent.children.length;i++)
            {
                if(parent.children[i].index !== parent.currentItem && parent.children[i].isSelected)
                {
                    parent.children[i].toggleSelected()
                }
            }
        }
    }
    clip: true
    height: container.height + bar.height
    Rectangle{
        id: bar
        anchors {
            top: parent.top
            left: parent.left
            right: parent.right
        }
        height: 30
        color:  root.isSelected ? "#81BEF7" : "#CEECF5"
        Text {
            anchors.fill: parent
            anchors.margins: 10
            horizontalAlignment: Text.AlignLeft
            verticalAlignment: Text.AlignVCenter
            text: root.title
        }
        Text {
            anchors{
                right: parent.right
                top: parent.top
                bottom: parent.bottom
                margins: 10
            }
            horizontalAlignment: Text.AlignRight
            verticalAlignment: Text.AlignVCenter
            text: "^"
            rotation: root.isSelected ? "180" : 0
        }
        MouseArea {
            id:panelAreaClick
            anchors.fill: parent
            cursorShape: Qt.PointingHandCursor
            onClicked: function(){
                toggleSelected()
            }
        }
    }
    Rectangle{
        id: container
        anchors.top: bar.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        height: loader.item && isSelected ? loader.item.height : 0
        Loader {
            id: loader
            visible: isSelected
            sourceComponent: content
            anchors.top: container.top
        }
        Behavior on height {
            PropertyAnimation { duration: 1000 }

        }
    }
}

Моя большая проблема в том, что я не могу найти способ предоставить что-то для content в функции createObject.

Я знаю, что могу передать динамическое содержимое в content, выполнив что-то вроде:

"content": "import QtQuick 2.0; Rectangle{}"

но это не то, что я хочу сделать, потому что у меня будет файл, созданный в файле, похожем на panellog.qml, это то, что я хочу передать аргументу content новой вкладки, которая будетбыть создан.

1 Ответ

0 голосов
/ 01 февраля 2019

Было бы проще просто указать, что в вашем встроенном компоненте:

        Component {
            id: panelItem
            PanelItem {
                title: qsTr("Teste")
                width: parent.width
                content: Item {}
            }
        }

Или вы можете установить тип content равным Component, чтобы вы могли передать ему другой встроенный компонентчто ... это почти одно и то же.Это может показаться слишком трудоемким, но на самом деле довольно удобно настраивать материал таким образом, чтобы он также давал вам доступ к текущей области действия компонента.

Проблема здесь в том, что Qt имеет двустороннее ограничение, которое является своего родапрепятствие:

  • вы не можете использовать декларативный синтаксис компонента в императивном (JS) коде
  • вы не можете декларативно создавать экземпляры встроенных компонентов

Это означает, что:

  • если вы хотите сослаться на декларативный объект, вы должны сделать это, используя его идентификатор или свойство - он будет работать только с идентификатором, а не с литералом объекта / экземпляром

  • Если вы хотите создать объект путем декальверации, он должен быть в выделенном файле qml

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...