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基礎學習(一) 基礎概念

 

如果您覺得文章不錯,不妨給個 打賞,寫作不易,感謝各位的支持。您的支持是我最大的動力,謝謝!!! 

 

  


很重要--轉載聲明

  1. 本站文章無特別說明,皆為原創,版權所有,轉載時請用鏈接的方式,給出原文出處。同時寫上原作者:朝十晚八 or Twowords
  2. 如要轉載,請原文轉載,如在轉載時修改本文,請事先告知,謝絕在轉載時通過修改本文達到有利於轉載者的目的。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM