How to use a ListView with custom item QML

匿名 (未验证) 提交于 2019-12-03 01:40:02

问题:

I am a newbie in QML. I made thanks to internet ressources this accordion:

Item {     default property var contentItem: null     property string title: "panel"     id: root     Layout.fillWidth: true     height: 30     Layout.fillHeight: current     property bool current: false     ColumnLayout {          anchors.fill: parent         spacing: 0         Rectangle {             Drag.active: dragArea.drag.active             id: bar             Layout.fillWidth: true             height: 30             color:  root.current ? "#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.current ? "180" : 0             }             MouseArea {                 id: dragArea                 anchors.fill: parent                 cursorShape: Qt.PointingHandCursor                 drag.axis: Drag.YAxis                  drag.target: root                  onReleased: {                      root.Drag.drop()                 }                 onClicked: {                     if (root.parent.current !== root) {                          root.current = !root.current;                          root.parent.currentItem = root;                     }                  }             }         }         Rectangle {             id: container             Layout.fillWidth: true             anchors.top: bar.bottom             implicitHeight: root.height - bar.height             clip: true             Behavior on implicitHeight {                 PropertyAnimation { duration: 100 }             }         }         Component.onCompleted: {             if(root.contentItem !== null)                root.contentItem.parent = container;         }     } }

PanelItem.qml

Window {     visible: true     width: 400; height: 400          ColumnLayout {             anchors.fill: parent             spacing: 1             id: test             property var currentItem: null             PanelItem {                 title: "Panel 1"                 Rectangle {                     color: "orange"                     anchors.fill: parent                 }             }             PanelItem {                 title: "Panel 2"                 Rectangle {                     color: "lightgreen"                     anchors.fill: parent                 }             }             PanelItem {                 title: "Panel 3"                 Rectangle {                     color: "lightblue"                     anchors.fill: parent                 }             }             PanelItem {                 title: "Panel 4"                 Rectangle {                     color: "yellow"                     anchors.fill: parent                 }             }             Item {                 Layout.fillWidth: true                 Layout.fillHeight: true             }         } }

main.qml

However, I wanted to be able to change items index (position) thanks to a "drag & drop" technique.

I read that it is not so good and easy to change index in a column layout. So I tried to put my accordion in a ListView but I am lost and it doesn't work at all.

I tried something like that:

Window {     visible: true     width: 400; height: 400     ListView {         id: my_list         anchors.fill: parent         model: 14         delegate: PanelItem {                 id: my_delegate                 title: "Panel 1"                 Rectangle {                     color: "orange"                     anchors.fill: parent                 }         }     } }

main.qml

Could someone help me to do and explain what I am doing wrong ?

Thanks a lot !

回答1:

Ok, some problems here:

  1. If you have your PanelItem not in a *Layout, you can't use the attached properties Layout.*. Therefore lines, such as Line 5: Layout.fillWidth = true won't work. Use width: parent.width or anchors { left: parent.left; right: parent.rigth } to set the width.

  2. I would not reccomend to use default property var contentItem, as this might lead to some forgotten objects. You can assign mutliple Items to this default property, where each new Item kicks out the former Item.

  3. Use a property Component contentItem instead, as e.g the QtQuick.Controls 2.0 do. Then use a Loader to instantiate this Component, when the PanelItem is expanded.
    Use a property Item contentItem if it should not be dynamicaly loaded and unloaded.
    Using the properties not as default makes sure, there is usually only one Item assigned.
    Usually it is only recommended to use the default property only together with something like alias someItem.data. If you use default property var someData you should listen to onSomeDataChanged and reassign the newly added object to some appropriate container. So if you want to allow multiple Items to be added, make it like this:

example.qml

Item {     default property alias contentItem.data     Item {         id: contentItem         width: childrenRect.width         height: childrenRect.height     } }

Use some line such as implicitHeight: barHeight + contentItemHeight where barHeight is the height of the bar, that is always visible, and the contentItemHeight is (collapsed ? 0 : loadedContentItem.height)

You might use a ObjectModel if it is just for the sake of reordering of the Items. Then you should not provide a delegate, as the ObjectModel supplies the delegate itself - or well rather the Object to be displayed than a delegate.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!