I want to make an horizontal listView works as a delegate for another veritcal listView, I've 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 listview scroll well but the horizontal one does not scroll. Any help? Thanks
I tried it once and it didn't work, the outer list handles all events. The solution was to have a Flickable additionally to the ListViews and anchor the contentX of the horizontal and contentY of the vertical lists to contentX and contentY of the Flickable.
Some 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
}
}
I tried this solution on the 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");
}
}
}
}
}
}
You have a MouseArea
in your vertical list view which steals all events to your horizontal ListView. Best practice in QML is to include all MouseArea
components inside the delegate.
Also, instead of using the indexAt(mouseX,mouseY)
method, use the index
property available to all delegates.
In order to propogate the mouse event from list delegate's MouseArea
to list2 delegate's 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
}
}
You can use z
property to make outer lists handle mouse events first.
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 this is a reliable and proper way though.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.