首页 文章

QML ListView的不同代表

提问于
浏览
16

我想知道是否可以使用(几个)不同的代表来获得QML ListView .

根据 ListView 模型中的单个对象,我想用不同的委托来可视化对象 .

这段代码解释了我想要实现的目标:

main.qml

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2

ApplicationWindow {
    title: qsTr("Hello World")
    width: 640
    height: 480
    visible: true

    ListModel {
        id: contactsModel
        ListElement {
            name: "Bill Smith"
            position: "Engineer"
        }
        ListElement {
            name: "John Brown"
            position: "Engineer"
        }
        ListElement {
            name: "Sam Wise"
            position: "Manager"
        }
    }

    ListView {
        id: contactsView
        anchors.left: parent.left
        anchors.top: parent.top
        width: parent.width
        height: parent.height
        orientation: Qt.Vertical
        spacing: 10
        model: contactsModel
        delegate: {
            if (position == "Engineer") return Employee;  //<--- depending on condition, load Contact{}
            else if (position == "Manager") return Manager; //<--- depending on condition, load Person{}
        }
    }
}

Employee.qml (我想用作代表的一个可能的组件)

import QtQuick 2.4

Rectangle{
    width: 200
    height: 50
    color: ListView.isCurrentItem ? "#003366" : "#585858"
    border.color: "gray"
    border.width: 1

    Text{
        anchors.centerIn: parent
        color: "white"
        text: name
    }
}

Manager.qml (我想用作委托的其他组件)

import QtQuick 2.4

Rectangle{
    width: 200
    height: 50
    color: "red"
    border.color: "blue"
    border.width: 1

    Text{
        anchors.centerIn: parent
        color: "white"
        text: name
    }
}

我很感激任何建议!谢谢!

5 回答

  • 10

    我相信最好为所有类型的 position 实现一个基本委托,它根据 position 或使用 Loader 的任何其他数据属性加载具体实现

    BaseDelegate {
        property var position
    
        Loader {
            sourceComponent: {
                switch(position) {
                    case "Engineer": return engineerDelegate
                }
            }
        }
    
        Component {
            id: engineerDelegate
            Rectangle {
                 Text {  }
            }
        }
    }
    
  • 5

    我遇到了同样的问题,Qt文档提供了一个很好的答案:http://doc.qt.io/qt-5/qml-qtquick-loader.html#using-a-loader-within-a-view-delegate

    最简单的解决方案是使用 Component 内联 Component 来设置 source 文件:

    ListView {
        id: contactsView
        anchors.left: parent.left
        anchors.top: parent.top
        width: parent.width
        height: parent.height
        orientation: Qt.Vertical
        spacing: 10
        model: contactsModel
        delegate: Component {
            Loader {
                source: switch(position) {
                    case "Engineer": return "Employee.qml"
                    case "Manager": return "Manager.qml"
                }
            }
        }
    }
    

    任何使用 Loader.srcComponent 的尝试都将导致缺少模型中的任何变量(包括 index ) . 变量存在的唯一方法是将子 Component 放在主 Component 中,但是只有一个可以存在,所以它没用 .

  • -1

    我实现如下:

    ListView {
        id: iranCitiesList
        model: sampleModel
        delegate: Loader {
            height: childrenRect.height
            width: parent.width
            sourceComponent: {
                switch(itemType) {
                case "image" :
                    return imageDel;
                case "video":
                    return videoDel;
                }
            }
        }
        ImageDelegate { id: imageDel }
        VideoDelegate { id: videoDel }
    }
    

    ImageDelegate.qml

    Component {
        Image { /*...*/ }
    }
    

    VideoDelegate.qml

    Component {
        Item { /*....*/ }
    }
    

    最后请注意,检查代表的宽度和高度 . 就我而言,我必须再次在 Loader 中设置我的委托的宽度和高度 .
    祝你好运 - 穆萨维

  • 0

    只要您只有两种类型,以下代码易于维护且易于理解:

    delegate: Item {
        Employee { visible = position === "Engineer" }
        Manager { visible = position === "Manager" }
    }
    

    如果类型的数量增加,它不是一个合适的解决方案,它很容易导致if语句的地狱 .

  • 9

    当然,这是可能的 . ListView.delegate 是一种指向 Component 的指针,它将绘制项目以便您可以更改它 .

    例如:

    Employee { id: delegateEmployee }
    Manager { id: delegateManager}
    ...
    ListView {  
        property string position   
        delegate: position == "Engineer" ? delegateEmployee : delegateManager
    }
    

相关问题