根据 listElement 键切换 listView 的委托
Posted
技术标签:
【中文标题】根据 listElement 键切换 listView 的委托【英文标题】:Switch delegate of listView based on listElement key 【发布时间】:2018-05-29 00:23:41 【问题描述】:我有一个动态填充的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】:如您所知,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
【讨论】:
感谢 folibis。这很奇怪!Loader
正在打破角色并能够交替代表,或者这实际上是结果。
ListView.delegate 是 Component
,因此 ListView 无论如何都会在需要时实例化项目。因此,您只需在 ListView 实例化 Loader
时添加一个小重载,然后实例化项目本身。 Qt 文档说:如果可能的话,将代理正常显示不需要的功能放在可以在需要时加载其他组件的加载器中。以上是关于根据 listElement 键切换 listView 的委托的主要内容,如果未能解决你的问题,请参考以下文章
QML程序实现动态切换多语言(ListModel/ListElement中的文本的多语言处理)
QML - 将 ListView 与动态生成的 ListElement 一起使用