Horizontal listView inside a vertical list in qml

I want the horizontal listView to work as a delegate for another veritcal listView, I wrote the following code:

import Qt 4.7 Item { id:main width: 360 height: 640 Component{ id:myDelegate ListView{ id:list2 spacing: 5 width:list.width height:list.height/3 interactive: true orientation: ListView.Horizontal model: ListModel { ListElement { name: "Bill Smith" number: "555 3264" } ListElement { name: "John Brown" number: "555 8426" } ListElement { name: "Sam Wise" number: "555 0473" } ListElement { name: "Sam Wise" number: "555 0473" } ListElement { name: "Sam Wise" number: "555 0473" } } delegate: Text{text:name width: main.width/3} focus: true MouseArea { anchors.fill: parent onClicked: { ListView.list2.currentIndex = ListView.list2.indexAt(mouseX, mouseY) } } } } ListView { id: list clip: true spacing: 5 anchors.fill: parent orientation: ListView.Vertical model: Model{} delegate:myDelegate // highlight: Rectangle { // width: list.currentItem.width // color: "lightsteelblue" // radius: 5 // } focus: true MouseArea { anchors.fill: parent onClicked: { list.currentIndex = list.indexAt(mouseX, mouseY) } } } } 

The vertical list is scanned well, but the horizontal one does not scroll. Any help? Thanks

+8
qt qt4 qml
source share
4 answers

I tried once, and it did not work, the external list processes all the events. The solution was to further add Flickable to ListViews and bind the content of X horizontal and contentY vertical lists to contentX and contentY from Flickable.

Some kind of semi-complete code to show the principle:

 Item { ListView { anchors.fill: parent clip: true orientation: ListView.Vertical interactive: false contentY: listController.contentY delegate: ListView { orientation: ListView.Horizontal interactive: false contentX: listController.contentX } } Flickable { id: listController anchors.fill: parent contentHeight: vert.contentHeight contentWidth: horizontalElement.width } } 
+6
source share

I tried this solution on a simulator and it worked.

 import QtQuick 1.1 import com.nokia.symbian 1.1 Page { id: mainPage anchors.fill: parent ListModel { id: colorsModel ListElement { colorCode: "red" } ListElement { colorCode: "green" } ListElement { colorCode: "blue" } ListElement { colorCode: "orange" } ListElement { colorCode: "white" } ListElement { colorCode: "purple" } ListElement { colorCode: "gray" } ListElement { colorCode: "yellow" } ListElement { colorCode: "purple" } } ListView { anchors.fill: parent model: 30 spacing: 20 cacheBuffer: 200 // in pixels delegate: ListView { width: parent.width; height: 50; spacing: 20 model: colorsModel orientation: ListView.Horizontal delegate: Rectangle { color: colorCode width: 50 height: 50 MouseArea { anchors.fill: parent onClicked: { console.log(colorCode + " clicked"); } } } } } } 
+3
source share

You have MouseArea in your list of vertical lists that steals all events into your horizontal ListView. The best practice in QML is to include all MouseArea components inside the delegate.

In addition, instead of using the indexAt(mouseX,mouseY) method indexAt(mouseX,mouseY) use the index property, which is available to all delegates.

To propagate the mouse event from the delegate of the MouseArea list to list2 delegate MouseArea , use mouse.accepted = false

 Item { id:main width: 360 height: 640 Component{ id:myDelegate ListView{ id:list2 spacing: 5 width:list.width height:list.height/3 interactive: true orientation: ListView.Horizontal model: ListModel { ListElement { name: "Bill Smith" number: "555 3264" } ListElement { name: "John Brown" number: "555 8426" } ListElement { name: "Sam Wise" number: "555 0473" } ListElement { name: "Sam Wise" number: "555 0473" } ListElement { name: "Sam Wise" number: "555 0473" } } delegate: Text { text:name width: main.width/3} focus: true MouseArea { anchors.fill: parent onClicked: { list2.currentIndex = index; } } } MouseArea { anchors.fill: parent onClicked: { list2.ListView.view.currentIndex = index; mouse.accepted = false; } } } ListView { id: list clip: true spacing: 5 anchors.fill: parent orientation: ListView.Vertical model: Model{} delegate:myDelegate focus: true } } 
+2
source share

You can use the z property to have external lists handle mouse events.

 ListView { z: 100 // put whatever you want or need delegate: ListView { z: 1000 // put whatever is above 100 } } 

Or even better:

 ListView { delegate: ListView { z: parent.z + 1 } } 

Not quite sure if this is a reliable and correct way.

0
source share

All Articles