在开发用户界面时,最好的办法是保持数据与可视化的分离。比如一个通讯录,可以用list展示,也可以用grid展示,这都属于view部分,可以不同。但是数据都是相同的,都有名称,头像,手机号等元素。QML针对这种场景提供了model-view框架。其实同样的模式在传统的QWidget 框架中也有,比如QListView 和QTableView。

一,实现起来,记住三个关键点:

1,model。 数据来源,一般是通过网络请求获取。

2,view。负责可视化显示,是ListView 还是GridView。

3,delegate。代理,就是怎么展示数据。它负责将model和view连接起来,将model中的每条数据通过具体的控件,渲染到view中。

下面通过一个例子,来说明代码的写法,这个例子类似一个通讯录,数据我们写死,真实情况应该是从接口获取。利用ListView进行可视化。代理是一个Rectangle 内部一个Image展示头像,一个Text 显示文本。

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.15

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

//可视化view
ListView{
anchors.fill: parent
width: 100
delegate: addressDelegate
model: model
}

//list 模型
ListModel{
id:model
}

//代理
Component{
id:addressDelegate
Rectangle{
width: 140
height: 120

RowLayout{
anchors.fill: parent
anchors.margins: 10
//头像
Image {
source: img
Layout.preferredWidth: 100
Layout.preferredHeight: 100
}
//名称
Text {
text: name
verticalAlignment: Text.AlignVCenter
}
}
}
}

//构造模型数据
Component.onCompleted: {
model.append({"img":"https://img2.baidu.com/it/u=607192830,2624468444&fm=253&fmt=auto&app=120&f=JPEG?w=1025&h=684","name":"刘备"})
model.append({"img":"https://img2.baidu.com/it/u=1662844506,2024543724&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=1052","name":"关羽"})
model.append({"img":"https://img2.baidu.com/it/u=2512544330,2343544095&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=300","name":"张飞"})
model.append({"img":"https://img2.baidu.com/it/u=4186203074,1390758742&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=618","name":"赵云"})
}
}

二,总结

这套模型还有很多用法,比如数据量特别大的时候,可以使用Flickable元素,同时可以限制代理数量。还可以动态的增加,删除模型。添加页眉页脚等。但是底层逻辑还是那三条,model 负责加载数据,view 负责显示,delegate负责具体每条数据如何展示。