QML中具有嵌套滚动区域的二维表

Posted

技术标签:

【中文标题】QML中具有嵌套滚动区域的二维表【英文标题】:Two-dimensional table with nested scrolling areas in QML 【发布时间】:2015-04-17 13:40:54 【问题描述】:

我想在 QML 中创建一个电视节目表,其中纵轴是频道列表,横轴是基于时间的。例如像

(来源:zappware.com)

最初,我创建了

一个垂直的 ListView model = 频道列表 delegate = 水平 ListView 每个水平的 ListView 都有 model = 事件列表 delegate = 宽度与事件持续时间成正比的项目

到目前为止一切顺利。唯一的缺点是水平的 ListView 一个一个滚动,而它们应该一起滚动。

因此,不知何故,每个水平 ListView 的 contentX 属性都应该绑定到移动/滑动的水平 ListView 的 contentX 属性。请注意,此绑定是动态的:在第一行中滑动时,所有其他行都应绑定到第一行的 contentX。但是在第二行中滑动时应该更改。

关于如何做到这一点的任何建议?

我尝试了一种不同的方法

在垂直 ListView 的顶部创建一个 Flickable Item(contentWidth 是完整的时间窗口)。 将每个水平 ListView 绑定到此 Flickable 的 contentX(这是一个静态绑定)

这导致了很好的同步滚动,但我仍然有一些问题

我不得不做一些技巧来确保轻弹只能是水平或垂直的,而不是两者兼而有之 我无法再点击个别事件;我猜事件被 Flickable 拦截了 我也不确定这种具有巨大 contentWidth 的 Flickable 对内存的影响?

感谢您的反馈!

【问题讨论】:

【参考方案1】:

我会说频道只有一个垂直列表视图。但只有频道名称,而不是实际节目。除了程序的水平视图,您可以将它们全部塞进一个可滑动的内容中,使用开始时间和持续时间通过将它们的 x 和宽度属性绑定到前者来在可滑动的内容中布局程序。

然后您可以将频道列表视图与节目项的垂直滚动绑定在一起,以便您拥有与相应频道对应的节目。这样,您可以从两者垂直滚动,而只能水平滚动程序。

这是一个简单的例子:

ApplicationWindow 
    id: main
    width: 500
    height: 100
    visible: true
    color: "white"

    ListModel 
        id: modC
        ListElement  name: "Ch1" 
        ListElement  name: "Ch2" 
        ListElement  name: "Ch3" 
    

    ListModel 
        id: modP1
        ListElement  name: "p1"; start: 0; duration: 6 
        ListElement  name: "p2"; start: 6; duration: 6 
        ListElement  name: "p3"; start: 12; duration: 6 
        ListElement  name: "p4"; start: 18; duration: 6 
    
    ListModel 
        id: modP2
        ListElement  name: "p1"; start: 0; duration: 12 
        ListElement  name: "p2"; start: 12; duration: 12 
    
    ListModel 
        id: modP3
        ListElement  name: "p1"; start: 0; duration: 8 
        ListElement  name: "p2"; start: 8; duration: 8 
        ListElement  name: "p3"; start: 16; duration: 8 
    

    property var subMod : [ modP1, modP2, modP3 ]

    Component 
        id: progDelegate
        Rectangle 
            property var source
            x: source.start * 50
            width: source.duration * 50
            height: 50
            color: "lightblue"
            border.color: "black"
            Text 
                text: source.name
            
        
    

    Row 
        anchors.fill: parent
        ListView 
            id: list
            height: parent.height
            width: 100
            model: modC

            delegate: Item 
                width: 100
                height: 50
                Rectangle 
                    anchors.fill: parent
                    color: "red"
                    border.color: "black"
                    Text 
                        anchors.centerIn: parent
                        text: name
                    
                
                Component.onCompleted: 
                    var mod = subMod[index]
                    for (var i = 0; i < mod.count; ++i) progDelegate.createObject(flick.contentItem, "source": mod.get(i), "y": index * 50)
                
            
        
        Flickable 
            id: flick
            height: parent.height
            width: parent.width - list.width
            contentWidth: 1200
            contentHeight: contentItem.childrenRect.height
            clip: true
            flickableDirection: Flickable.HorizontalFlick
            contentY: list.contentY
        
    

【讨论】:

谢谢!很多!但是有两个问题:1)在您的示例中,垂直滚动仅适用于频道列,而不适用于节目区域,而您似乎另有说明(“这样您可以从两者垂直滚动,并且只能水平滚动节目。”) . 2) 知道内容宽度/高度N很大的几乎空的 Flickable 的内存使用情况是什么 1 - 我在写完之前的文本 20 分钟后写了这个例子。在那段时间里,我认为只在频道中进行垂直滚动会更“理智”。您可以进行双向绑定,删除现有的并使用两个视图的onContentYChanged 来同步另一个。 2 - 它不占用任何内存,它是“虚构区域”,只是逻辑,它不像是每个像素都填充的位图。 明白!感谢您帮助我。

以上是关于QML中具有嵌套滚动区域的二维表的主要内容,如果未能解决你的问题,请参考以下文章

如何将鼠标滚轮滚动添加到垂直滚动条或滚动区域?

如何在具有两个视图的 QML 中使用包?

嵌套滚动区域

在listView QML中使用嵌套JSON作为section.property。

嵌套的 UIScrollViews 和事件路由

带有自定义滚动条的 QML Listview