使用模型与视图来定义用户界面时,代理在创建显示时扮演了大量的角色,在模型中的每个元素通过代理来实现可视化。
代理
使用键盘移动 高亮 效果
代码:
视图绑定的属性是 ListView.isCurrentItem: 这个属性是一个布尔值,标识这个元素是否是 视图的当前元素,也就是否当前元素获取到 焦点。
每个代理的width(宽度)属性与视图的width(宽度)属性绑定,每个代理的背景颜色color 依赖绑定的属性ListView.isCurrentItem 属性。
动画添加与移除元素(Animating Added and Removed Items)
动画添加与移除效果
QML 视图为每个代理绑定了两个信号,onAdd和onRemove 。使用动画连接它们。使⽤动画连接它们,可以⽅便创建识别哪些内容被添加或删除 的动画。
调用模型的 append 方法来添加一个新的元素,点击添加操作会 触发视图创建⼀个新的代理,并发送 GridView.onAdd信号。SequentialAnimation队列动画与这个信号连接绑定, 使⽤代理的scale属性来放⼤视图元素。
import QtQuick 2.15Rectangle{width: 200height: 300color: "white"// ListView{// anchors.fill: parent// anchors.margins: 20// model: 100// clip: true// delegate: numberDelegateTest// spacing: 5// focus: true// }// Component{// id: numberDelegateTest// Rectangle{// width: ListView.view.width// height: 40// color: ListView.isCurrentItem ? "gray" : "lightGreen"// Text {// anchors.centerIn: parent// font.pixelSize: 20// text: index// }// }// }ListModel{id: theListModelListElement{number:0}ListElement{number:1}ListElement{number:2}ListElement{number:3}ListElement{number:4}ListElement{number:5}ListElement{number:6}ListElement{number:7}ListElement{number:8}}Rectangle{anchors.left: parent.leftanchors.right: parent.rightanchors.bottom: parent.bottomanchors.margins: 20height: 40color: "darkGreen"Text {anchors.centerIn: parenttext: "add Item!"}MouseArea{//parent是当前对外象外的 也就是当前花括号外面的对象anchors.fill: parentonClicked: {theListModel.append({"number": ++parent.count})}}property int count: 9}GridView{anchors.fill: parentanchors.margins: 20anchors.bottomMargin: 80clip: truemodel: theListModelcellWidth: 45cellHeight: 45delegate: numberDelegateTest2}Component{id: numberDelegateTest2Rectangle{id:wrapperTestwidth: 40height: 40color: "lightGreen"Text{anchors.centerIn: parentfont.pixelSize: 10text: number}MouseArea{anchors.fill: parentonClicked: {if(!wrapperTest.GridView.delayRemove)theListModel.remove(index)}}GridView.onRemove: SequentialAnimation {PropertyAction { target: wrapperTest; property: "GridView.delayRemove"; value: true }NumberAnimation { target: wrapperTest; property: "scale"; to: 0; duration: 250; easing.type: Easing.InOutQuad }PropertyAction { target: wrapperTest; property: "GridView.delayRemove"; value: false }}GridView.onAdd: SequentialAnimation {NumberAnimation { target: wrapperTest; property: "scale"; from: 0; to: 1; duration: 250; easing.type: Easing.InOutQuad }}}}
}
形变的代理
包装器(wrapper)的高度(height)被设置为链表视图(ListView)的高度。标签图片被放大并且下移,使图片 从小图片的位置 向 大图片的位置移动。 两个隐藏项, 实际视图(factsView)与 关闭按键(closeButton)切换它的 透明度(opacity 属性) 显示出来。
设置链表视图(ListView)包含了设置内容Y坐标(constemtsY)这是视图顶部可见的部分代理的 Y轴坐标。 另一个变化是设置视图的交互(interactive)为false。 这个操作阻止了视图的移动,用户不能动条切换当前项。
效果图:
左侧文本标题
右侧图片
图片源为 ListElement 中属性 名称(imageSource)
说明文本视图
文本内容也是ListElement 中属性 facts
关闭按钮
点击事件
状态
动画
完整代码
import QtQuick 2.15Rectangle{width: 1600height: 600color: "white"// ListView{// anchors.fill: parent// anchors.margins: 20// model: 100// clip: true// delegate: numberDelegateTest// spacing: 5// focus: true// }// Component{// id: numberDelegateTest// Rectangle{// width: ListView.view.width// height: 40// color: ListView.isCurrentItem ? "gray" : "lightGray"// Text {// anchors.centerIn: parent// font.pixelSize: 20// text: index// }// }// }// ListModel{// id: theListModel// ListElement{// number:0// }// ListElement{// number:1// }// ListElement{// number:2// }// ListElement{// number:3// }// ListElement{// number:4// }// ListElement{// number:5// }// ListElement{// number:6// }// ListElement{// number:7// }// ListElement{// number:8// }// }// Rectangle{// anchors.left: parent.left// anchors.right: parent.right// anchors.bottom: parent.bottom// anchors.margins: 20// height: 40// color: "darkGreen"// Text {// anchors.centerIn: parent// text: "add Item!"// }// MouseArea{// //parent是当前对外象外的 也就是当前花括号外面的对象// anchors.fill: parent// onClicked: {// theListModel.append({"number": ++parent.count})// }// }// property int count: 9// }// GridView{// anchors.fill: parent// anchors.margins: 20// anchors.bottomMargin: 80// clip: true// model: theListModel// cellWidth: 45// cellHeight: 45// delegate: numberDelegateTest2// }// Component{// id: numberDelegateTest2// Rectangle{// id:wrapperTest// width: 40// height: 40// color: "lightGreen"// Text{// anchors.centerIn: parent// font.pixelSize: 10// text: number// }// MouseArea{// anchors.fill: parent// onClicked: {// if(!wrapperTest.GridView.delayRemove)// theListModel.remove(index)// }// }// GridView.onRemove: SequentialAnimation {// PropertyAction { target: wrapperTest; property: "GridView.delayRemove"; value: true }// NumberAnimation { target: wrapperTest; property: "scale"; to: 0; duration: 250; easing.type: Easing.InOutQuad }// PropertyAction { target: wrapperTest; property: "GridView.delayRemove"; value: false }// }// GridView.onAdd: SequentialAnimation {// NumberAnimation { target: wrapperTest; property: "scale"; from: 0; to: 1; duration: 250; easing.type: Easing.InOutQuad }// }// }// }ListView{id: listViewTestanchors.fill: parentdelegate: detailsDelegatemodel: planets}ListModel{id: planetsListElement { name: "Mercury"; imageSource: "ufo.jpg"; facts: "Mercury is the smallest planet in the Solar System. It is the closest planet to the sun. It makes one trip around the Sun once every 87.969 days." }ListElement { name: "Venus"; imageSource: "SiC.jpeg"; facts: "Venus is the second planet from the Sun. It is a terrestrial planet because it has a solid, rocky surface. The other terrestrial planets are Mercury, Earth and Mars. Astronomers have known Venus for thousands of years." }ListElement { name: "Earth"; imageSource: "football1.jpeg"; facts: "The Earth is the third planet from the Sun. It is one of the four terrestrial planets in our Solar System. This means most of its mass is solid. The other three are Mercury, Venus and Mars. The Earth is also called the Blue Planet, 'Planet Earth', and 'Terra'." }ListElement { name: "Mars"; imageSource: "football.jpg"; facts: "Mars is the fourth planet from the Sun in the Solar System. Mars is dry, rocky and cold. It is home to the largest volcano in the Solar System. Mars is named after the mythological Roman god of war because it is a red planet, which signifies the colour of blood." }}Component{id: detailsDelegateItem {id: wrapperwidth: listViewTest.widthheight: 30Rectangle{anchors.left: parent.leftanchors.right: parent.rightanchors.top: parent.topheight: 30color: "#ffaa00"Text {anchors.left: parent.leftanchors.verticalCenter: parent.verticalCenterfont.pixelSize: parent.height-4text: name}}Rectangle{id: imageTestcolor: "black"anchors.right: parent.rightanchors.top: parent.topanchors.rightMargin: 2anchors.topMargin: 2width: 26height: 26Image {anchors.fill: parentfillMode: Image.PreserveAspectFitsource: imageSource}}MouseArea{anchors.fill: parentonClicked: {parent.state = "expanded"console.log(name + "被点击")}}Item {id: factsViewanchors.top: imageTest.bottomanchors.left: parent.leftanchors.right: parent.rightanchors.bottom: parent.bottomopacity: 0Rectangle{anchors.fill: parentcolor: "#cccccc"Text {anchors.fill: parentanchors.margins: 5clip: truewrapMode: Text.WordWrapfont.pixelSize: 12text: facts}}}Rectangle{id: closeButtonanchors.right: parent.rightanchors.top: parent.topanchors.rightMargin: 2anchors.topMargin: 2width: 26height: 26color: "red"opacity: 0MouseArea {anchors.fill: parentonClicked: wrapper.state = ""}Text{anchors.fill: parentanchors.horizontalCenter: parent.horizontalCenteranchors.verticalCenter: parent.verticalCenterfont.pixelSize: 26text: "X"}}states:[State {name: "expanded"PropertyChanges { target: wrapper; height: listViewTest.height }PropertyChanges { target: imageTest; width: listViewTest.width; height: listViewTest.height -200; anchors.rightMargin: 0; anchors.topMargin: 30 }PropertyChanges { target: factsView; opacity: 1 }PropertyChanges { target: closeButton; opacity: 1 }PropertyChanges { target: wrapper.ListView.view; contentY: wrapper.y; interactive: false }}]transitions: [Transition {NumberAnimation {duration: 200;properties: "height,width,anchors.rightMargin,anchors.topMargin,opacity,contentY"}}]}}}
遇到的问题
- 点击没反应 expanded 状态拼写错误 导致状态切换不了
- 图片设置高度不对 导致文本不显示
- 包装状态切换被注释导致 显示有问题 导致切换条目显示不到图片下面