Qt QML:同步滚动多个列表视图
我想要一个带有(水平)ListView委托的单个(垂直)ListView 水平代理应同步滚动。为此,我将Flickable放在ListView的顶部,并将水平ListView的contentX绑定到Flickable的contentX(垂直ListView的contentX也是如此)(注意:同步ListView滚动描述了不同的方法,但这在移动设备上似乎有性能问题) 下面的代码可以正常工作,但仍然存在以下问题Qt QML:同步滚动多个列表视图,qt,listview,mouseevent,qml,Qt,Listview,Mouseevent,Qml,我想要一个带有(水平)ListView委托的单个(垂直)ListView 水平代理应同步滚动。为此,我将Flickable放在ListView的顶部,并将水平ListView的contentX绑定到Flickable的contentX(垂直ListView的contentX也是如此)(注意:同步ListView滚动描述了不同的方法,但这在移动设备上似乎有性能问题) 下面的代码可以正常工作,但仍然存在以下问题 我没有得到矩形中的onclick(我在移除顶部Flickable时得到它) 我想要水平
- 我没有得到矩形中的onclick(我在移除顶部Flickable时得到它)
- 我想要水平轻弹或垂直轻弹,但不能同时使用两者。我可以通过设置
来限制顶部Flickable的轻弹,但是我不能再垂直轻弹了(我希望Flickable可以将未使用的鼠标事件传递到垂直列表视图,但这似乎没有发生)flickableDirection:Flickable.horizontalfick
import QtQuick 2.0
Item {
id: main
visible: true
width: 600
height: 600
ListView {
id: verticalList
width: parent.width;
height: parent.height;
contentY : flickable.contentY
anchors.fill: parent
spacing: 10
orientation: ListView.Vertical
model: 100
delegate:
ListView {
id: horizontalList
width: parent.width;
height: 100;
contentX : flickable.contentX
spacing: 10
orientation: ListView.Horizontal
model: 20
property var verticalIndex : index
delegate:
Rectangle
{
property var colors : ['red', 'green', 'blue']
property var widths : [100, 200, 300]
height: 100
width: widths[(verticalIndex + model.index) % widths.length]
color: colors[model.index % colors.length]
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Rectangle.onClicked")
}
}
}
}
}
//on top a Flickable
Flickable {
id: flickable
height: parent.height
width: parent.width
contentHeight: 100*100 //nrOfRows * rowHeight
contentWidth: 20*300 //nrOfEvent * max/averageEventWidth
}
}
我不是给你一个完美的解决方案,但它是有效的。当您使用
列表视图顶部的Flickable
时,您将无法与其交互。因此,我使用了Flickable
在ListView
下面,并将Flickable
和ListView
的contentX
绑定,但这会导致循环,我得到以下输出,但我们得到了所需的行为
QML Binding: Binding loop detected for property "value"
编辑
因此,我没有对垂直列表使用ListView
,而是使用了Repeater
和Column
并使用了属性绑定。现在很好用
以下是更新版本
import QtQuick 2.0
Item {
id: main
visible: true
width: 600
height: 600
property bool virticalFlick: false //To get either vertical or horizontal flicking
Flickable {
anchors.fill: parent
contentWidth: contentItem.childrenRect.width
contentHeight: contentItem.childrenRect.height
flickableDirection: Flickable.VerticalFlick
interactive: (virticalFlick === true)?true:false
Column {
id: column
spacing: 10
Repeater {
id: repeater
model: 20
ListView {
id: horizontalList
width: 600;
height: 100;
clip: true
interactive: (virticalFlick === true)?false:true
spacing: 10
orientation: ListView.Horizontal
model: 20
property var verticalIndex : index
onMovingChanged: {
if(moving == true) {
for(var i=0; i<repeater.count ; i++) {
/* If the property is later assigned a static value from a JavaScript statement,
this will remove the binding.
However if the intention is to create a new binding then the property
must be assigned a Qt.binding() value instead. This is done by passing a function to
Qt.binding() that returns the desired result */
if (i !== index)
repeater.itemAt(i).contentX = Qt.binding(function() { return contentX });
}
}
else {
for(var i=0; i<repeater.count ; i++) {
if (i !== index)
repeater.itemAt(i).contentX = contentX; // This will remove binding
}
}
}
delegate: Rectangle {
property var colors : ['red', 'green', 'blue']
property var widths : [100, 200, 300]
height: 100
width: widths[(ListView.view.verticalIndex + model.index) % widths.length]
color: colors[model.index % colors.length]
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Rectangle.onClicked")
}
}
}
}
}
}
}
}
导入QtQuick 2.0
项目{
id:main
可见:正确
宽度:600
身高:600
属性bool virticalFlick:false//以获取垂直或水平的flicking
轻快的{
锚定。填充:父级
contentWidth:contentItem.childrenRect.width
contentHeight:contentItem.childrenRect.height
flickableDirection:Flickable.VerticalFlick
交互式:(virticalFlick==真)?真:假
纵队{
id:列
间距:10
中继器{
id:中继器
型号:20
列表视图{
id:horizontalList
宽度:600;
身高:100;
剪辑:对
交互式:(virticalFlick==真)?假:真
间距:10
方向:ListView.Horizontal
型号:20
属性变量verticalIndex:索引
onMovingChanged:{
如果(移动==真){
对于(var i=0;i而言,以下方法确实有效,但最初的尝试似乎更为优雅
我仍然需要比较轻弹时的性能(fps),特别是在移动设备上。我也收到“绑定循环”警告,但我认为它们是误报
import QtQuick 2.0
Item {
id: main
visible: true
width: 600
height: 600
ListView {
id: verticalList
width: parent.width;
height: parent.height;
anchors.fill: parent
spacing: 10
cacheBuffer: 500 // in pixels
orientation: ListView.Vertical
model: 100
property var activeIndex : 0
property var lastContentX : 0
delegate:
ListView {
id: horizontalList
width: parent.width;
height: 100;
spacing: 10
cacheBuffer: 500 // in pixels
orientation: ListView.Horizontal
model: 20
property var verticalIndex : index
delegate:
Rectangle
{
property var colors : ['red', 'green', 'blue']
color: colors[model.index % colors.length]
height: 100
property var widths : [100, 200, 300]
width: widths[(verticalIndex + model.index ) % widths.length]
MouseArea {
z:10
anchors.fill: parent
onClicked: {
console.log("Rectangle.onClicked")
}
onPressed: {
console.log("Rectangle.onPressed")
}
onReleased: {
console.log("Rectangle.onReleased")
}
}
}
onContentXChanged: {
if(model.index === verticalList.activeIndex)
{
verticalList.lastContentX = contentX
}
}
onMovementStarted: {
verticalList.activeIndex = model.index
unbind();
}
onMovementEnded: {
bind();
}
Component.onCompleted: {
bind();
}
function bind()
{
contentX = Qt.binding(function() { return verticalList.lastContentX })
}
function unbind()
{
contentX = contentX ;
}
}
}
}
我最初的尝试需要进行以下修改
- 将
Flickable
限制为Flickable方向:Flickable.horizontalfick
并删除verticalList上的contentY:Flickable.contentY
- 这样,就不再有垂直滚动。可以通过在
列表视图中移动Flickable
来解决这一问题
- 通过将以下
MouseArea
添加到Flickable
例如
感谢您的输入。水平翻转确实不平滑(立即停止),很可能是由于绑定循环。但我可能会在此版本的基础上进行更多的实验。再次感谢!翻转现在确实平滑。但是,我确实需要一个ListView iso a中继器(因为中继器在可见窗口外使用了更多的内存和油漆,这在设置QSG_VISUALIZE=overdraw时可以看到)。此外,我需要垂直和水平滚动(但没有我最初尝试的对角线滚动)。我的答案符合这些要求,但我仍然需要比较两个选项的wrt性能。其中有许多绑定循环。我认为这将导致一些主要的性能问题。
MouseArea {
anchors.fill: parent
//see http://stackoverflow.com/questions/29236762/mousearea-inside-flickable-is-preventing-it-from-flicking
onReleased: {
if (!propagateComposedEvents) {
propagateComposedEvents = true
}
}
}