qml中垂直列表视图内的水平列表视图

Posted

技术标签:

【中文标题】qml中垂直列表视图内的水平列表视图【英文标题】:Horizontal listView inside Vertical Listview in qml 【发布时间】:2011-10-20 07:44:34 【问题描述】:

我想让一个水平 listView 作为另一个垂直 listView 的委托,我编写了以下代码:

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: Texttext: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)
            
        
    

垂直的列表视图滚动良好,但水平的不滚动。 有什么帮助吗? 谢谢

【问题讨论】:

【参考方案1】:

我试了一次还是不行,外部列表处理所有事件。解决方案是在 ListViews 之外添加一个 Flickable,并将水平列表的 contentX 和垂直列表的 contentY 锚定到 Flickable 的 contentX 和 contentY。

一些半完整的代码来展示原理:

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
    


【讨论】:

是的另一种解决方案是从垂直列表中删除焦点:true【参考方案2】:

我在模拟器上尝试了这个解决方案,它奏效了。

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】:

您的垂直列表视图中有一个MouseArea,它将所有事件窃取到您的水平列表视图。 QML 的最佳实践是在委托中包含所有 MouseArea 组件。

另外,不要使用indexAt(mouseX,mouseY) 方法,而是使用所有代表都可用的index 属性。

为了将鼠标事件从列表委托的MouseArea 传播到列表2 委托的MouseArea,请使用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
    

【讨论】:

嗨,有没有为每个内部列表视图设置 ListModel(来自 cpp)的解决方案?【参考方案4】:

您可以使用z 属性使外部列表首先处理鼠标事件。

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

甚至更好:

ListView 
    delegate: ListView 
        z: parent.z + 1        
    

虽然不太确定这是一种可靠且正确的方法。

【讨论】:

以上是关于qml中垂直列表视图内的水平列表视图的主要内容,如果未能解决你的问题,请参考以下文章

在垂直列表视图中颤动动态高度水平列表视图

在 Flutter 的垂直列表中添加动态高度水平列表视图

来自模型的 QML 树视图

如何获得列表视图的水平滚动和垂直滚动?

堆栈小部件内的列表视图不起作用(滚动方向:Axis.vertical)

QML - 垂直滑动视图?