Reputation: 593
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 !
Upvotes: 0
Views: 2356
Reputation: 13711
Ok, some problems here:
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.
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
.
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 Item
s. 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.
Upvotes: 1