首页 > 代码库 > qml基础学习 模型视图(一)

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中的imageSource102                 }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: false195                     }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: 018 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基础学习(一) 基础概念

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