前言

当使用模型与视图来自定义用户界面时,代理在创建显示时扮演了大量的角色。在模型中的每个元素通过代理来实现可视化,用户真实可见的是这些代理元素。

代理

每个代理访问的索引号或者或绑定属性一部分来自数据模型,一部分来自视图。来自模型的数据将会通过属性传递到代理。来自视图的数据将会通过属性传递视图中与代理相关的状态信息。

通常使用的视图绑定属性是ListView.isCurrentItem和ListView.view。第一个是一个布尔值,标识这个元素是否是视图当前元素,这个值是只读的,引用自当前视图。通过访问视图,可以创建可复用的代理,这些代理在被包含时会自动匹配视图的大小。在下面这个例子中,每个代理的width与视图的width属性绑定,每个代理的背景颜色color依赖于绑定的属性ListView.isCurrentItem属性。

import QtQuick 2.3import QtQuick.Window 2.2Window {    id: root    visible: true    width: 120    height: 300    color: "white"    ListView {        anchors.fill: parent        anchors.margins: 20        clip: true        model: 100        delegate: numberDelegate        spacing: 5        focus: true    }    Component {        id: numberDelegate        Rectangle {            width: ListView.view.width            height: 40            color: ListView.isCurrentItem ? "green" : "lightGreen"            Text {                anchors.centerIn: parent                font.pixelSize: 10                text: index            }        }    }}

运行效果如下:

如果在模型中的每个元素与一个动作相关,例如点击作用于一个元素时,这个功能是代理完成的。这是由事件管理分配给视图的,这个操作控制了视图中元素的导航,代理控制了特定元素上的动作。最基础的方法是在每个代理中创建一个MouseArea并且响应onClicked信号,在后面的文章中会演示相关的例子。

动画添加与移除元素

在某些情况下,视图中的显示内容会随着时间而改变。由于模型数据的改变,元素会添加或移除。在这种情况下,一个比较好的方法是使用可视化队列给用户一个方向的感觉,来帮助用户知道哪些数据被加入或者移除。

为了方便使用,QML视图为每个代理绑定了两个信号,onAdd和onRemove。使用动画连接它们,可以方便创建识别哪些内容被添加或者删除的动画。

下面这个例子演示了如何动态填充一个ListModel。在屏幕下方,有一个添加新元素的按钮。当点击它时,会调用模型的append方法来添加一个新的元素。这个操作会触发视图创建一个新的代理,并发送GridView.onAdd信号。SequentialAnimation队列动画与这个信号连接绑定,使用代理的scale属性来放大视图元素。

当视图中的一个代理点击时,将会调用模型的remove方法将一个元素从模型中移除。这个操作将会导致GridView.onRemove信号的发送,触发另一个SequentialAnimation。这时,代理的销毁将会延迟直到动画完成。为了完成这个操作,PropertyAction元素需要在动画前设置GridView.delayRemove属性为true,并在动画后设置为false。这样确保了动画在代理项移除前完成。

GridView.onRemove: SequentialAnimation {                PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: true }                NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: Easing.InOutQuad }                PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: false }            }            GridView.onAdd: SequentialAnimation {                NumberAnimation { target: wrapper; property: "scale"; from: 0; to: 1; duration: 250; easing.type: Easing.InOutQuad }            }

运行效果如下:

形变代理

在使用链表时通常会使用当前项激活时展开的机制。这个操作可以被用于动态的将当前的项目填充到整个屏幕来添加一个新的用户界面,或者为链表中的当前项提供更多的信息。

在下面的例子中,当点击链表项时,链表项都会展开填充整个ListView。额外的间隔区域被用于添加更多的信息,这种机制使用了一个状态来控制,当一个链表项展开时,代理项都能输入expanded状态,在这种状态下一些属性被改变。

首先wrapper的height被设置为ListView的高度。标签图片被方法并且下移,使图片从小图片的位置移动到大图片的位置。除了这些之外,两个隐藏项,实际视图(factView)与关闭按键(closeButton)切换它的opacity(透明度)显示出来。最后设置ListView。

设置ListView包含了设置内容Y坐标,这是视图顶部可见的部分代理的Y轴坐标。另一个变化是设置视图的交互(interactive)为false。这个操作阻止了视图的移动,用户不再能够通过滚动条切换当前项。

由于设置第一个链表项为可点击,向它输入一个expanded状态,导致了它的代理项被填充到整个链表并且内容重置。当点击关闭按钮时,清空状态,导致它的代理项返回上一个状态,并且重新设置ListView有效。

import QtQuick 2.3import QtQuick.Window 2.2Window {    id: root    visible: true    width: 480    height: 300    color: "white"    Item {        width: 300        height: 480        Rectangle {            anchors.fill: parent            gradient: Gradient {                GradientStop { position: 0.0; color: "#4a4a4a" }                GradientStop { position: 1.0; color: "#2b2b2b" }            }        }        ListView {            id: listView            anchors.fill: parent            delegate: detailsDelegate            model: planets        }        ListModel {            id: planets            ListElement { name: "Mercury"; imageSource: "image/mercury.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: "image/venus.jpg"; 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: "image/earth.jpg"; 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: "image/mars.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: detailsDelegate            Item {                id: wrapper                width: listView.width                height: 30                Rectangle {                    anchors.left: parent.left                    anchors.right: parent.right                    anchors.top: parent.top                    height: 30                    color: "#333"                    border.color: Qt.lighter(color, 1.2)                    Text {                        anchors.left: parent.left                        anchors.verticalCenter: parent.verticalCenter                        anchors.leftMargin: 4                        font.pixelSize: parent.height-4                        color: '#fff'                        text: name                    }                }                Rectangle {                    id: image                    width: 26                    height: 26                    anchors.right: parent.right                    anchors.top: parent.top                    anchors.rightMargin: 2                    anchors.topMargin: 2                    color: "black"                    Image {                        anchors.fill: parent                        fillMode: Image.PreserveAspectFit                        source: imageSource                    }                }                MouseArea {                    anchors.fill: parent                    onClicked: parent.state = "expanded"                }                Item {                    id: factsView                    anchors.top: image.bottom                    anchors.left: parent.left                    anchors.right: parent.right                    anchors.bottom: parent.bottom                    opacity: 0                    Rectangle {                        anchors.fill: parent                        gradient: Gradient {                            GradientStop { position: 0.0; color: "#fed958" }                            GradientStop { position: 1.0; color: "#fecc2f" }                        }                        border.color: '#000000'                        border.width: 2                        Text {                            anchors.fill: parent                            anchors.margins: 5                            clip: true                            wrapMode: Text.WordWrap                            color: '#1f1f21'                            font.pixelSize: 12                            text: facts                        }                    }                }                Rectangle {                    id: closeButton                    anchors.right: parent.right                    anchors.top: parent.top                    anchors.rightMargin: 2                    anchors.topMargin: 2                    width: 26                    height: 26                    color: "#157efb"                    border.color: Qt.lighter(color, 1.1)                    opacity: 0                    MouseArea {                        anchors.fill: parent                        onClicked: wrapper.state = ""                    }                }                states: [                    State {                        name: "expanded"                        PropertyChanges { target: wrapper; height: listView.height }                        PropertyChanges { target: image; width: listView.width; height: listView.width; 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"                        }                    }                ]            }        }    }}

运行效果如下:

这个例子展示了展开代理来填充视图能够简单的通过代理的形变来完成。

qml 信号槽第二次才响应_QML中各种代理的用法相关推荐

  1. QT源码剖析-QT对象通信机制信号槽的绑定具体实现

    本文详细介绍QT核心机制之一 信号和槽. 我们在此根据Qt源代码一步一步探究其信号槽的实现过程. 核心知识点: 模板元编程技术. Qt moc预编译机制. QObject类. 目录 1. QObjec ...

  2. VS2008 Qt Designer 中自定义信号槽

    一.Qt Designer自定义槽函数 发现:在VS2008 +Qt4.7  中打开ui文件,所用的英文QT Designer工具,没有转到槽函数的功能,不如QtCreator自带的QtDesigne ...

  3. Qt connect parent widget 连接父控件的信号槽

    Qt中的信号槽系统是不同类中间传递数据的神器,如果连接父子空间之间的信号槽很重要,在父类中实例化子类的时候一定要注意将父类连上,不然信号槽无法使用,比如若子类是个对话框Dialog类,一定不要忘了加t ...

  4. qt信号发送间隔短而槽耗时多_Qt信号槽问题汇总 - osc_9q1dp3jk的个人空间 - OSCHINA - 中文开源技术交流社区...

    1. 发送一次信号,调用多次槽函数问题 在同一个类中,多次链接QObject::connect(sender, SIGNAL(signalSender(QString, int)), receiver ...

  5. 【探究】信号槽到底能不能有返回值?

    [探究]信号槽到底能不能有返回值? 前言 Qt信号槽到底可不可以有返回值呢?问了下身边的同事,有的人说可以,有的人说不可以.在实际项目中,确实没看到过有人使用带返回值的信号槽,可以说存在感很低.平时大 ...

  6. Qt的信号槽机制介绍

    Qt 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象.易于扩展.真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 Qt ...

  7. Hello Qt——Qt信号槽机制源码解析

    基于Qt4.8.6版本 一.信号槽机制的原理 1.信号槽简介 信号槽是观察者模式的一种实现,特性如下: A.一个信号就是一个能够被观察的事件,或者至少是事件已经发生的一种通知: B.一个槽就是一个观察 ...

  8. 1.QT元对象系统、信号槽概述、宏Q_OBJECT

    一.元对象系统(Meta-Object System) Qt添加C++原本不具备的元对象系统,元对象系统提供了信号槽机制,运行时类型信息和动态属性系统. 元对象系统基于三点: 1.元对象系统为以QOb ...

  9. Qt / Moc 和信号 - 槽解析

    目录 一. MOC 二. moc_test.cpp 分析 三. connect 四. activate 五. 总结 版本 Qt5.12.3 moc_test.cpp 位于可执行文件目录下,其余源代码都 ...

最新文章

  1. RabbitMQ 入门系列(7)— 如何保证 RabbitMQ 高可用性
  2. 【Computer Vision】 复现分割网络(1)——SegNet
  3. Spring-使用加密的属性文件02
  4. C/C++ ltoa函数 - C语言零基础入门教程
  5. 华为鸿蒙山海,华为包圆了整部《山海经》,鸿蒙是何意?还有青龙白虎朱雀玄武?...
  6. Telephone Wire(POJ-3612)
  7. C++_函数_函数的占位参数_函数重载---C++语言工作笔记034
  8. 观看台式计算机组成观后感,计算机组成原理实验一:运算器实验
  9. linux dhcp 绑定mac地址,●DHCP协议的功能是 (58) 。在Linux中提供DHCP服务的程序是 (59) ;DHCP服务将主机的MAC地址和IP地 - 赏学吧...
  10. 论文的参考文献如何对齐。
  11. 更精确的新旧中国居民身份证号码验证算法
  12. cesium 泛光 bloom效果
  13. 四.树莓派4B-更换系统源
  14. OS - 浅谈操作系统的内存管理
  15. 微信发展简史:微信成功的必然和偶然
  16. ONES 通过 CMMI 3 级评估认证
  17. 关于 curl: (52) Empty reply from server 问题的一种解决方案
  18. 运算放大器的稳定性分析(一)
  19. butter中文意思_butter是什么意思中文翻译
  20. 征信 - 信用的价值

热门文章

  1. 51单片机的轮胎气压监测系统_汽车的胎压监测系统有哪些作用?
  2. 计算机汉字的输入和编辑教案,计算机汉字录入教案
  3. oracle ns,RAC到单实例SWITCHOVER
  4. mysql事务隔离级别 花_mysql事务隔离级别
  5. OpenShift 4 - 通过 secret 访问受保护的镜像
  6. (四)为深度伪造预处理数据集
  7. ML.NET 9月更新
  8. java跨库调用存储_java-调用spring数据其余存储库方法不会返回...
  9. wechat.php+获取昵称,微信后台代码,获取用户昵称
  10. pythonseleniumide使用_selenium第二课(脚本录制seleniumIDE的使用)