QML ListView的不同代表

dh1*_*1tw 20 qt listview qml qtquick2

我想知道是否可以使用(几个)不同的代表进行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{}
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Aur*_*ert 15

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

最简单的解决办法是内联ComponentLoader设置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"
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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


And*_*rii 11

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

BaseDelegate {
    property var position

    Loader {
        sourceComponent: {
            switch(position) {
                case "Engineer": return engineerDelegate
            }
        }
    }

    Component {
        id: engineerDelegate
        Rectangle {
             Text {  }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


S.M*_*avi 8

我实现如下:

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 }
}
Run Code Online (Sandbox Code Playgroud)


ImageDelegate.qml

Component {
    Image { /*...*/ }
}
Run Code Online (Sandbox Code Playgroud)


VideoDelegate.qml

Component {
    Item { /*....*/ }
}
Run Code Online (Sandbox Code Playgroud)

最后请注意,检查代表的宽度和高度.在我的情况下,我不得不再次设置我的代表的宽度和高度Loader.
祝你好运 - 穆萨维


小智 6

现在最简单的方法是使用DelegateChooser。这也允许您编辑委托的属性,这是使用 Loader 更难做的事情!

示例灵感来自文档:

import QtQuick 2.14
import QtQuick.Controls 2.14
import Qt.labs.qmlmodels 1.0

ListView {
    width: 640; height: 480

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

    DelegateChooser {
        id: chooser
        role: "position"
        DelegateChoice { roleValue: "Manager"; Manager { ... } }
        DelegateChoice { roleValue: "Employee"; Employee { ... } }
    }

    model: contractsModel
    delegate: chooser
}
Run Code Online (Sandbox Code Playgroud)

  • 这应该是现在的正确答案,因为默认的 Qt 组件 (2认同)

fol*_*bis 0

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

例如:

Employee { id: delegateEmployee }
Manager { id: delegateManager}
...
ListView {  
    property string position   
    delegate: position == "Engineer" ? delegateEmployee : delegateManager
}
Run Code Online (Sandbox Code Playgroud)