我有一种情况,我需要一个包含自己类型的 ListView 的组件。这是一个简化版本:
myComp.qml
import QtQuick
Item {
Text {
id: name
text: qsTr("Hello")
}
ListView{
model: 5
delegate: MyComp{}
}
}
main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
MyComp{
}
}
qmldir.txt
MyComp 1.0 myComp.qml
运行此命令后,我得到了预期的
recursive instantiation error
。
我的主要问题是:
正如 @Atmo 在评论中提到的,您不能自行声明类型。但是,在您的情况下,不会发生无限循环。
据我所知,有两种选择可以解决您的问题:
最简单的选择是使用加载器 [1]。我还建议使用 DelegateChooser 在委托之间切换,因为您不需要在所有子项和写入条件等上使用 Loader
例如:
组.qml
import QtQuick
import QtQuick.Controls
import Qt.labs.qmlmodels
Control {
id: control
property alias model: listview.model
padding: 5
DelegateChooser {
id: chooser
role: 'type'
DelegateChoice {
roleValue: 'data'
Control {
required property var modelData
padding: 5
contentItem: Row {
spacing: 5
Repeater {
model: modelData.data
Label {
required property string modelData
padding: 5
width: 35
text: modelData
background: Rectangle {
radius: 2; border { width: 1; color: '#ccc'}
}
}
}
}
background: Rectangle {
radius: 5
border { width: 1; color: '#eee'}
}
}
}
DelegateChoice {
roleValue: 'group'
Loader {
required property var modelData
source: 'Group.qml'
width: control.availableWidth
onLoaded: item.model = modelData.data
}
}
}
contentItem: ListView {
id: listview
implicitHeight: contentHeight
spacing: 5
delegate: chooser
}
background: Rectangle {
color: '#aafbf3dd'
radius: 5; border { width: 1; color: '#dcc896'}
}
}
用法如下:
Group {
anchors.fill: parent
model: [
{type: 'data', data: [1,2,3]},
{
type: 'group',
data: [
{type: 'data', data: [4,5,6,7]},
{type: 'data', data: [8,9,10,11]},
{type: 'group', data: [{type: 'data', data: [12,13,14]}]},
]
},
]
}
预览:
这是一种更干净的方法,因为它不需要 Loader,但它确实需要使用多个文件,这很好。这是一个简化的示例:
组.qml
import QtQuick
import QtQuick.Controls
Control {
id: control
property alias model: listview.model
padding: 5
property Component delegate: Item {}
contentItem: ListView {
id: listview
spacing: 5
implicitHeight: contentHeight
delegate: control.delegate
}
background: Rectangle {
color: '#aafbf3dd'
radius: 5; border { width: 1; color: '#dcc896'}
}
}
Delegate.qml(简化版)
import QtQuick
import QtQuick.Controls
import Qt.labs.qmlmodels
DelegateChooser {
id: chooser
role: 'type'
DelegateChoice {
roleValue: 'data'
Row {
required property var modelData
spacing: 5
Repeater {
model: modelData.data
Label {
required property string modelData
text: modelData
}
}
}
}
DelegateChoice {
roleValue: 'group'
Group {
required property var modelData
width: ListView.view.parent.width - 10
model: modelData.data
delegate: chooser
}
}
}
用法保持不变:
Group {
anchors.fill: parent
model: [ /* same data */ ]
delegate: Delegate {}
}
预览: