根据listElement键切换listView的委托

时间:2018-05-29 00:23:42

标签: qt qml

我有一个动态填充的ListModel。我想为模型中的一个元素选择/切换委托(所有其他元素应该用另一个委托查看),这可能吗?

我的QML模型有两个加载的组件委托。我希望当listElement的“键”与值(“link”)匹配时,委托被设置为其中一个组件。我通过设置listView.delegate来做到这一点;问题是选择似乎有效,但它会递归更改所有元素(包括已经加载的元素)的委托,最终我只为listView加载了一个委托。

我在SO中看到了很多解决方案,但没有一个与我的用例匹配,因为大多数情况下这个post似乎相似,但它动态加载委托组件,我不确定它是否有效,我不知道我想最终动态加载组件。这是我的QML代码,包括我如何填充模型并选择委托:

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Window 2.3

Window {
    visible: true
    id: mainQML
    width: 640
    height: 480

    title: qsTr("Offers View")
    Item {
        id: offersPage

        ListModel{
            id: barcdeLockupOffers
            // model will be dynamically populated.
            // Depending on value of key , I want to select listView delegete.
            ListElement {
                key: ""
                value: ""
            }
        }
        Component {
            id: offersTextDelegate
            Rectangle {
                id: offersRect
                anchors { left: parent.left; right: parent.right}
                height: offersColumn.implicitHeight + 4
                border.width: 1
                border.color: "lightsteelblue"
                radius: 2
                Column {
                    id: offersColumn
                    //Text { text: "Merchent: " + merchant ; property bool useStyle: true}
                    Text {
                        id: offerdata
                        text: '<font color="blue" size=14> <b>' + key +':' + '</b> </font>'  + value + '\n\n';
                        width: mainQML.width - 40
                        height: 30
                        wrapMode: Text.Wrap
                    }
                }
            }
        }
        Component {
            id: offersHTTPDelegate
            Rectangle {
                id: offersRect2
                anchors { left: parent.left; right: parent.right}
                height: offersColumn2.implicitHeight + 4
                border.width: 1
                border.color: "lightsteelblue"
                radius: 2
                Column {
                    id: offersColumn2
                    Text {
                        text: "<a href=" + value + ">" + "Click here for Offer details" + "</a>"
                        color: "blue"
                        property bool useStyle: true
                        MouseArea{
                            anchors.fill: parent
                            onClicked: {
                                parent.color="grey"
                                Qt.openUrlExternally(value)
                            }
                        }
                    }
                }
            }
        }

        ListView {
            id: offersView
            anchors.top: parent.top
            height: mainQML.height - 100
            anchors.margins: 10
            model: barcdeLockupOffers
        }
    }
    Component.onCompleted: {
        barcdeLockupOffers.clear();
        var listModelKeys= ["Title", "Price", "Condition", "Avalability", "link"]
        var listModelValues = ["Coffee Machine", "14", "New", "Available", "https://www.amazon.com/Nespresso-VertuoPlus-Coffee-Espresso-DeLonghi/dp/B01NBJ2UT5/ref=sr_1_1_sspa?s=home-garden&ie=UTF8&qid=1527543544&sr=1-1-spons&keywords=coffee+maker&psc=1"]

        for (var x = 0 ; x < listModelKeys.length ; x++){
            barcdeLockupOffers.append({key: listModelKeys[x] , value: listModelValues[x]})
            //console.log("Key = : " +  listModelKeys[x])
            if (listModelKeys[x] === "link")
                offersView.delegate = offersHTTPDelegate
            else
                offersView.delegate = offersTextDelegate
        }
    }
}

1 个答案:

答案 0 :(得分:1)

如您所知,delegate对所有项都是通用的,您不能为指定项指定不同的委托。 最简单的方法是使用Loader,例如:

import QtQuick 2.10
import QtQuick.Window 2.2

Window {
    visible: true
    width:480
    height: 640
    title: qsTr("Test")

    Component {
        id: type1
        Rectangle {
            color: "yellow"
            anchors.fill: parent
        }
    }
    Component {
        id: type2
        Rectangle {
            color: "orange"
            anchors.fill: parent
        }
    }

    ListView {
        anchors.fill: parent
        model: 10
        delegate: Loader {
            sourceComponent: index % 2 ? type1 : type2
            height: 30
            width: parent.width
        }
    }
}