qml基础学习 模型视图(一)

一、理解qml模型和视图

qt的发展是迅速的,虽然在每一个release版本中或多或少都有bug,但是作为一个庞大的gui库,no,应该说是一个开发框架开说,qt已经算是做的相当好。qml部分是qt4.7的时候推出的,当时qml只是为了移动端而设计的开发语言,随着it行业的发展,桌面端也产生了一定的需求,这就使得qml也必须支持桌面端的开发。使用qml可以做出绚丽的界面,并把逻辑和界面展示分开,qml和C++就好比html和JavaScript。

qt中有大量的model/view类,视图类:QTableView、QListView和QTreeView,模型类:QAbstractTableModel、QAbstractListModel和QAbstractProxyModel,这三个模型类都是继承自QAbstractItemModel。对于qml语言来说,也有model和view,他们分别就是GridView、ListView和PathView,其中GridView和ListView在qt中都有对于的实现类,PathView是最难理解的view,也是最灵活的view,他可以做出各种各样比较绚丽的效果。

二、效果展示

这一节我们主要是说明qml中的视图类,如下效果图展示的那样,图1是用GridView实现,图2是用ListView实现,view的item项都是用代理进行绘制;图3是用PathView实现的一个效果图,类似于一个卡牌弹出弹入效果。

顺道提一嘴,qml文件都是可以使用qmlscene.exe来预览

图1 gridview效果图

图2 listview效果图

图3 pathview效果图

三、源码分析

每一个示例中都有大量的注释,具体细节可以参看注释

1、GridView增删

如图1所示,这是一个GridView的简单示例,示例完成单击Add Item按钮实现新增项,点击项实现删除等功能。

  1 import QtQuick 2.0
  2
  3 Rectangle {
  4     width: 480;
  5     height: 300;
  6
  7     //背景色渐变
  8     gradient: Gradient {
  9         GradientStop { position: 0.0; color: "#dbddde"; }
 10         GradientStop { position: 1.0; color: "#5fc9f8"; }
 11     }
 12
 13     //list模型默认9项
 14     ListModel {
 15         id: theModel
 16
 17         ListElement { number: 0; }
 18         ListElement { number: 1; }
 19         ListElement { number: 2; }
 20         ListElement { number: 3; }
 21         ListElement { number: 4; }
 22         ListElement { number: 5; }
 23         ListElement { number: 6; }
 24         ListElement { number: 7; }
 25         ListElement { number: 8; }
 26         ListElement { number: 9; }
 27     }
 28
 29     //Add Item按钮
 30     Rectangle {
 31         anchors.left: parent.left;
 32         anchors.right: parent.right;
 33         anchors.bottom: parent.bottom;
 34         anchors.margins: 20;
 35
 36         height: 40;
 37
 38         color: "#53d769";
 39         border.color: Qt.lighter(color, 1.1);
 40
 41         Text {
 42             anchors.centerIn: parent;
 43
 44             text: "Add item!";
 45         }
 46
 47         //点击时新增项  实现model的动态新增
 48         MouseArea {
 49             anchors.fill: parent;
 50
 51             onClicked: {
 52                 theModel.append({"number": ++parent.count});
 53             }
 54         }
 55
 56         property int count: 9;//
 57     }
 58
 59     GridView {
 60         anchors.fill: parent;
 61         anchors.margins: 20;
 62         anchors.bottomMargin: 80;
 63
 64         clip: true;
 65
 66         model: theModel;//绑定数据源
 67
 68         cellWidth: 45;//设置项大小
 69         cellHeight: 45;
 70
 71         delegate: numberDelegate;//设置绘制代理
 72     }
 73
 74     //自定义绘制代理
 75     Component {
 76         id: numberDelegate;
 77
 78         Rectangle {
 79             id: wrapper;
 80
 81             width: 40;
 82             height: 40;
 83
 84             //首先是一个渐变的矩形框
 85             gradient: Gradient {
 86                 GradientStop { position: 0.0; color: "#f8306a"; }
 87                 GradientStop { position: 1.0; color: "#fb5b40"; }
 88             }
 89
 90             //文本值是number的数值
 91             Text {
 92                 anchors.centerIn: parent;
 93
 94                 font.pixelSize: 10;
 95
 96                 text: number;
 97             }
 98
 99             //鼠标点击代理时,移除点击项
100             MouseArea {
101                 anchors.fill: parent;
102
103                 onClicked: {
104                     if (!wrapper.GridView.delayRemove)//是否延迟移除
105                     {
106                         theModel.remove(index);
107                     }
108                 }
109             }
110
111             //GridView移除项  顺序动画
112             GridView.onRemove: SequentialAnimation {
113                 //属性变化
114                 PropertyAction {
115                     target: wrapper;
116                     property: "GridView.delayRemove";
117                     value: true;
118                 }
119                 //数字动画
120                 NumberAnimation {
121                     target: wrapper;//目标对象
122                     property: "scale";//执行动画的属性
123                     to: 0;//结束值
124                     duration: 250;//动画持续时长
125                     easing.type: Easing.InOutQuad;//动画执行曲线
126                 }
127                 PropertyAction {
128                     target: wrapper;
129                     property: "GridView.delayRemove";
130                     value: false;
131                 }
132             }
133
134             //GridView新增项  顺序动画
135             GridView.onAdd: SequentialAnimation {
136                 NumberAnimation {
137                     target: wrapper;
138                     property: "scale";
139                     from: 0;//开始值
140                     to: 1;
141                     duration: 250;
142                     easing.type: Easing.InOutQuad;
143                 }
144             }
145         }
146     }
147 }

2、列表

如图2所示,是一个使用ListView实现的列表控件,点击列表控件中的项,可以实现最大化来展示列表的详细信息

  1 import QtQuick 2.0
  2
  3 Item {
  4     width: 300;
  5     height: 480;
  6
  7     //渐变别景色
  8     Rectangle {
  9         anchors.fill: parent;
 10         gradient: Gradient {
 11             GradientStop { position: 0.0; color: "#4a4a4a"; }
 12             GradientStop { position: 1.0; color: "#2b2b2b"; }
 13         }
 14     }
 15
 16     //主界面列表视图
 17     ListView {
 18         id: listView;
 19
 20         anchors.fill: parent;
 21
 22         delegate: detailsDelegate;//设置绘制代理
 23         model: planets;//绑定数据源
 24     }
 25
 26     ListModel {
 27         id: planets;
 28
 29         ListElement {
 30             name: "Mercury";
 31             imageSource: "images/mercury.jpeg";
 32             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." ;
 33         }
 34         ListElement {
 35             name: "Venus";
 36             imageSource: "images/venus.jpeg";
 37             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.";
 38         }
 39         ListElement {
 40             name: "Earth";
 41             imageSource: "images/earth.jpeg";
 42             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‘.";
 43         }
 44         ListElement {
 45             name: "Mars";
 46             imageSource: "images/mars.jpeg";
 47             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.";
 48         }
 49     }
 50
 51     Component {
 52         id: detailsDelegate;
 53
 54         Item {
 55             id: wrapper;
 56
 57             width: listView.width;
 58             height: 30;
 59
 60             //列表项文本
 61             Rectangle {
 62                 anchors.left: parent.left;
 63                 anchors.right: parent.right;
 64                 anchors.top: parent.top;
 65
 66                 height: 30;
 67
 68                 color: "#333";
 69                 border.color: Qt.lighter(color, 1.2);
 70                 Text {
 71                     anchors.left: parent.left;
 72                     anchors.verticalCenter: parent.verticalCenter;
 73                     anchors.leftMargin: 4;
 74
 75                     font.pixelSize: parent.height-4;
 76                     color: ‘#fff‘;
 77
 78                     text: name;//ListElement中的name
 79                 }
 80             }
 81
 82             //列表项图标
 83             Rectangle {
 84                 id: image;
 85
 86                 width: 26;
 87                 height: 26;
 88
 89                 anchors.right: parent.right;
 90                 anchors.top: parent.top;
 91                 anchors.rightMargin: 2;
 92                 anchors.topMargin: 2;
 93
 94                 color: "yellow";
 95
 96                 Image {
 97                     anchors.fill: parent;
 98
 99                     fillMode: Image.PreserveAspectFit;
100
101                     source: imageSource;//ListElement中的imageSource
102                 }
103             }
104
105             //鼠标点击列表项 进行状态前切换,
106             MouseArea {
107                 anchors.fill: parent;
108                 onClicked: parent.state = "expanded";//切换到展开状态
109             }
110
111             //详情页展开时,文本详细信息
112             Item {
113                 id: factsView;
114
115                 anchors.top: image.bottom;//位于放大后的图标底部
116                 anchors.left: parent.left;
117                 anchors.right: parent.right;
118                 anchors.bottom: parent.bottom;
119
120                 opacity: 0;//默认透明不显示  当点击代理项时该属性会慢慢变得可见
121
122                 Rectangle {
123                     anchors.fill: parent;
124
125                     gradient: Gradient {
126                         GradientStop { position: 0.0; color: "#fed958"; }
127                         GradientStop { position: 1.0; color: "#fecc2f"; }
128                     }
129                     border.color: ‘#000000‘;
130                     border.width: 2;
131
132                     Text {
133                         anchors.fill: parent;
134                         anchors.margins: 5;
135
136                         clip: true;//可剪切
137                         wrapMode: Text.WordWrap;//文本支持换行
138                         color: ‘#1f1f21‘;
139
140                         font.pixelSize: 12;
141
142                         text: facts;
143                     }
144                 }
145             }
146
147             //项最大化时 右上角关闭按钮
148             Rectangle {
149                 id: closeButton;
150
151                 anchors.right: parent.right;
152                 anchors.top: parent.top;
153                 anchors.rightMargin: 2;
154                 anchors.topMargin: 2;
155
156                 width: 26;
157                 height: 26;
158
159                 color: "#157efb";
160                 border.color: Qt.lighter(color, 1.1);
161
162                 opacity: 0;
163
164                 MouseArea {
165                     anchors.fill: parent;
166                     onClicked: wrapper.state = "";//点击恢复到默认状态
167                 }
168             }
169
170             //自定义代理状态
171             states: [
172                 State {
173                     name: "expanded";
174                     //在点击列表项后 各项属相变化
175
176                     //代理高度铺满视图高度
177                     PropertyChanges { target: wrapper; height: listView.height; }
178                     //列表项的图标放大
179                     PropertyChanges {
180                         target: image;
181                         width: listView.width;
182                         height: listView.width;
183                         anchors.rightMargin: 0;
184                         anchors.topMargin: 30//距离顶部30像素
185                     }
186                     //文本详细信息可见
187                     PropertyChanges { target: factsView; opacity: 1; }
188                     //关闭按钮可见
189                     PropertyChanges { target: closeButton; opacity: 1; }
190                     //列表项视图
191                     PropertyChanges {
192                         target: wrapper.ListView.view;
193                         contentY: wrapper.y;
194                         interactive: false
195                     }
196                 }
197             ]
198
199             //项变化时 过程
200             transitions: [
201                 Transition {
202                     NumberAnimation {
203                         duration: 200;
204                         properties: "height,width,anchors.rightMargin,anchors.topMargin,opacity,contentY";
205                     }
206                 }
207             ]
208         }
209     }
210 }

3、卡牌效果

示例代码可以直接放在qml文件中使用qmlscene.exe来预览

 1 import QtQuick 2.6
 2
 3 Rectangle {
 4     id: root;
 5     width: 480;
 6     height: 300;
 7
 8     PathView
 9     {
10         anchors.fill: parent;
11
12         delegate: flipCardDelegate;
13         model: 100;
14
15         path: Path{
16             startX: root.width / 2;
17             startY: 0
18
19             PathAttribute { name: "itemAngle"; value: -45.0; }
20             PathAttribute { name: "itemScale"; value: 0.5; }
21             PathAttribute { name: "itemZ"; value: 0; }//属性值附加到代理上面
22             PathLine { x: root.width/2; y: root.height*0.4; }//路径元素定义
23             PathPercent { value: 0.48; }//控制两个元素之间的路径所占百分比
24             PathLine { x: root.width/2; y: root.height*0.5; }
25             PathAttribute { name: "itemAngle"; value: 0.0; }
26             PathAttribute { name: "itemScale"; value: 1.0; }
27             PathAttribute { name: "itemZ"; value: 100 }
28             PathLine { x: root.width/2; y: root.height*0.6; }
29             PathPercent { value: 0.52; }
30             PathLine { x: root.width/2; y: root.height; }
31             PathAttribute { name: "itemAngle"; value: 45.0; }
32             PathAttribute { name: "itemScale"; value: 0.5; }
33             PathAttribute { name: "itemZ"; value: 0; }
34         }
35
36         pathItemCount: 17;//可见元素数目
37
38         preferredHighlightBegin: 0.5;
39         preferredHighlightEnd: 0.5;
40     }
41     Component{
42         id: flipCardDelegate;
43
44         Rectangle{
45             id: wrapper;
46
47             width: 64;
48             height: 64;
49             antialiasing: true;//反锯齿
50
51             //代理背景色渐变
52             gradient: Gradient{
53                 GradientStop { position: 0.0; color: "#2ed5fa"; }
54                 GradientStop { position: 1.0; color: "#2467ec"; }
55             }
56
57             visible: PathView.onPath;//在PathView上的项可见,不在视图上的项不可见
58
59             scale: PathView.itemScale;//缩放
60             z: PathView.itemZ;//z值  数值大的在上面
61
62             property variant rotX: PathView.itemAngle;//属性别名 主要是因为要在底下这个旋转过程中使用
63
64             //动画过程旋转
65             transform: Rotation {
66                 axis { x: 1; y: 1; z: 1; }//绕x轴旋转
67                 angle: wrapper.rotX;//旋转角度
68                 origin { x: 32; y: 32; }//旋转基点
69             }
70             Text{
71                 anchors.horizontalCenter: parent.horizontalCenter;
72                 anchors.verticalCenter: parent.verticalCenter;
73                 text: index;
74             }
75         }
76     }
77 }

四、相关文章

  qml基础学习(一) 基础概念

时间: 2024-12-16 17:10:11

qml基础学习 模型视图(一)的相关文章

学习模型-视图-控制器MVC模式

MVC简介: MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式.MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式: Model(模型)表示应用程序核心(比如数据库记录列表). View(视图)显示数据(数据库记录). Controller(控制器)处理输入(写入数据库记录). MVC 模式同时提供了对 HTML.

QML中的模型/视图 十二

QML中对于数据的存储和显示使用模型/视图框架. 1. QML数据模型 视图项目(如ListView.GridView和Repeater等)需要使用数据模型来为其提供数据进行显示.这些项目通常也需要一个委托(delegate)组件来为模型中的每一个条目创建一个实例.模型可以是静态的,也可以进行动态的修改.插入.移除或者移动项目.Qt帮助参考QML Data Models关键字. Item{ width:200; height:250 ListModel{ id:myModel ListEleme

qml基础学习(一) 基础概念

一.概括 学习qt已有2年多的时间,从qt4.7开始使用直到现在正在使用的qt5.6,基本都在windows机器上做开发.最近有意向看了下qt的qml部分,觉着还是挺不错的,毕竟可以做嵌入式移动端产品的部分,还是值的一学.后来在网上看了一些资料,算是初步了解了下qml,所以想就自己学习的过程做以记录,也方便自己理解,如果你有机会看到这篇文章,那么我认为你也是来学习qml的,如果你已经是一个有很强qml开发经验的老手,那么这篇文章和接下来的qml学习系列的文章你都不用看下去了,呵呵... 关于qm

SQL基础学习_04_视图

视图 1. 视图的创建 ? ? 视图就是保存好的SELECT语句,这些SELECT语句执行之后会产生新的表,所以在SQL中,视图和表是不做差别对待的,也就是SQL也可以对视图做一些操作: ? ? 由于视图并不实际保存数据,只是保存了执行的SELECT语句,可以节约存储空间,但是对于大数据量的存储,使用视图来频繁操作的话,势必会占用较大的计算时间,也算是一种用时间换空间的方案. ? ? 通过以下语句创建视图: ? ? CREATE VIEW 视图名称 (<视图列1>,<视图列2>,&

ASP.Net MVC开发基础学习笔记(3):Razor视图引擎、控制器与路由机制学习

首页 头条 文章 频道                         设计频道 Web前端 Python开发 Java技术 Android应用 iOS应用 资源 小组 相亲 频道 首页 头条 文章 小组 相亲 资源 设计 前端 Python Java 安卓 iOS 登录 注册 首页 最新文章 经典回顾 开发 Web前端 Python Android iOS Java C/C++ PHP .NET Ruby Go 设计 UI设计 网页设计 交互设计 用户体验 设计教程 设计职场 极客 IT技术

Qt 学习之路:模型-视图高级技术

PathView PathView是 QtQuick 中最强大的视图,同时也是最复杂的.PathView允许创建一种更灵活的视图.在这种视图中,数据项并不是方方正正,而是可以沿着任意路径布局.沿着同一布局路径,数据项的属性可以被更详细的设置,例如缩放.透明度等. 使用PathView首先需要定义一个代理和一个路径.除此之外,PathView还可以设置很多其它属性,其中最普遍的是pathItemCount,用于设置可视数据项的数目:preferredHighlightBegin.preferred

ASP.Net MVC开发基础学习笔记:三、Razor视图引擎、控制器与路由机制学习

一.天降神器“剃须刀” — Razor视图引擎 1.1 千呼万唤始出来的MVC3.0 在MVC3.0版本的时候,微软终于引入了第二种模板引擎:Razor.在这之前,我们一直在使用WebForm时代沿留下来的ASPX引擎或者第三方的NVelocity模板引擎. Razor在减少代码冗余.增强代码可读性和Visual Studio智能感知方面,都有着突出的优势.Razor一经推出就深受广大ASP.Net开发者的喜爱. 1.2 Razor的语法 (1)Razor文件类型:Razor支持两种文件类型,分

CSS基础学习十四:盒子模型补充之display属性设置

我在CSS基础学习十三:盒子模型的i博文只是阐释了CSS盒子模型,并没有过多的使用实例来演示.这篇博文 就来做一些盒子模型知识的补充.这一部分对于网页总体布局还是蛮重要的,过去大多数使用HTML中的table元素和 框架标签来进行网页的整体布局,现在我们使用最多的是DIV+CSS网页布局.所以一定要掌握好盒子模型,记住 content,border,padding和margin各自在盒子中的作用和使用方式. 先来看一个完整元素的盒子模型实例: <!DOCTYPE html PUBLIC "

CSS基础学习十五:盒子模型补充之外边距合并

今天继续接着CSS盒子模型补充,CSS基础学习十三:盒子模型和CSS基础学习十四:盒子模型补充之display属 性设置都是介绍了盒子模型中的内容概括.开始今天的主题:外边距合并. 外边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距.合并后的外边距的高度等于两个发生合 并的外边距的高度中的较大者. (1)外边距合并 外边距合并叠加是一个相当简单的概念.但是,在实践中对网页进行布局时,它会造成许多混淆.简单地说,外 边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距.合并后的