QML中的模型/视图 十二

Posted Dkma像疯子一样战斗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QML中的模型/视图 十二相关的知识,希望对你有一定的参考价值。

QML中对于数据的存储和显示使用模型/视图框架。

1. QML数据模型

    视图项目(如ListView、GridView和Repeater等)需要使用数据模型来为其提供数据进行显示。这些项目通常也需要一个委托(delegate)组件来为模型中的每一个条目创建一个实例。模型可以是静态的,也可以进行动态的修改、插入、移除或者移动项目。Qt帮助参考QML Data Models关键字。

 Item{
    width:200; height:250

    ListModel{
    id:myModel
    ListElement{type:"Dog";age:8}
    ListElement{type:"Cat";age:5}
    }

    Component{
    id:myDelegate
    Text{
        text:type+","+age
    }
    }

    ListView{
    anchors.fill: parent
    model:myModel
    delegate:myDelegate
    }
    }

  

详细介绍该例子。这里使用ListView来进行显示,在其中的数据模型model用来提供数据,委托delegate用来设置数据的显示方式。这里分别指定了myModel和myDelegate对象。在ListModel中,可用使用ListElemetn添加条目,每一个条目中可以有多种类型的角色,比如这里由两个type和age,并分别指定了值。而委托可以使用一个组件来实现,在委托中可以之间绑定数据模型中的角色,比如这里将type和age的值显示在了一个Text文本中。委托:简单来说就是数据模型中每一条目显示的时候都会使用委托提供的显示方式进行显示,可以看作一个模板。

     如果模型的属性和委托的属性出现了名字冲突,那么角色可以通过限定模型名称来访问。例如,委托中的Text元素中也有一个type或者age属性,那么其文本将会显示为他的属性值,而不是模型中type和age的值。这种情况下可以使用model.type和model.age来确保委托中可以显示正确的模型中的值。

      委托中还可以使用index角色,它包含了模型中条目的索引值。

 

1.1 ListModel

     ListModel是一个简单的具有层次的元素,可以使用ListElement属性来指定可用的角色。

     ListElement{name:"Apple"; cost:2.45} 模型中的两个角色 name和 cost。 他们可以绑定到ListView的委托上进行显示。如:

ListView{
    anchors.fill:parent
    model:fruitModel
    delegate:Row{
    Text{text:"Fruit:"+name}
    Text{text:"Cost:" + cost}
    }
}

  ListModel提供了函数来直接使用JaveScript操纵ListModel。在这种情况下,第一个插入的条目决定了使用该模型的视图中可用的而角色。

 

1.2 XmlListModel

     xmlListModel允许从一个XML数据源创建一个模型。该数据模型一般用来显示从网络上获取的数据,因为网络上数据都可以使用XML格式读取。

 

1.3 VisualItemModel

      VisualItemModel允许使用QML项目作为模型。这个模型同时包含了数据和委托。在其子项目中提供委托的内容,该模型没有提供任何角色。

     VisualItemModel{
     id:itemModel
     Rectangle{height:30;width:80;color:"red"}
     Rectangle{height:30;width:80;color:"green"}
     Rectangle{height:30;width:80;color:"blue"}
     }

     ListView{
     anchors.fill: parent;
     model:itemModel
     }

  

    QML还可以使用C++代码定义模型,对应参考文献:QML Data Models关键字对应的文档的 C++ Data Models部分内容。

 

1.4 在委托中访问视图和模型

     可以在委托中访问使用该委托的视图及其属性,例如使用ListView时,可以在委托中使用ListView.view来进行访问。而且还可以在委托中访问模型及其属性,例如使用ListView时,可以使用ListView.view.model来访问。这对于在多个视图中使用相同的委托但对于每一个视图又想用不同特色的情况是非常有用的。

 

2. 在QML中呈现数据

     Qt Quick包含了一组可以使用不同方式呈现数据的标准项目。对于简单的用户界面,可以将repeaters和positioners一起使用来包含一些数据并将它们排列在用户界面上。然而,当涉及大量的数据时,更好的办法是使用模型和视图来进行显示。

    视图是一个包含条目集合的可滚动容器,功能丰富,支持典型应用程序中的多种使用情况,而且还可以进行自定义风格和行为来满足需求。在Qt Quick基本图形元素中提供了一组标准的视图:

  • ListView在水平或者垂直列表中排列条目;
  • GridView在可用空间中将条目排列在一个网络中;
  • PathView在路径上排列条目。

    与这些视图不同,WebView不是一个功能完整的视图项目,需要和Flickable项目一起使用来创建一个视图,实现的功能与网页浏览器相似。在Qt手册中查看Presenting Data with QML关键字。

 

2.1 ListView

    ListView可以显示一个水平或者垂直放置条目的条目列表。ListView拥有一个模型model属性,用来定义要显示的数据。还有一个委托delegate属性,用来定义数据显示的方式。默认具有弹动效果。模型model可以单独定义在一个文件中,作为组件来使用。

 Rectangle{
     width:180;height:200

     Component{
     id:contactDelegate
     Item{
     width:180;height:40
     Column{
        Text{text:\'<b>Name:</b>\'+name}
        Text{text:\'<b>Number:</b>\'+number}
     }
     }
     }

     ListView{
       anchors.fill: parent
       model:ContactModel{}
       delegate: contactDelegate
       highlight:Rectangle{color:"lightsteelblue";radius: 5}
       focus:true; //键盘专用
     }
     }

  添加model组件

//ContactModel
ListModel { ListElement{ name:"Bill Smith" number:"555 364" } ListElement{ name:"John Brown" number:"555 846" } ListElement{ name:"Sam Wise" number:"555 0473" } }

  运行结果如下:

   

     例子中,ListView创建一个ContactModel组件作为其模型。使用highlight属性,可以指定当前选择项目的高亮。设置focus属性为了确保可以使用键盘来导航列表视图。键盘可以控制矩形块。

    ListView在委托的根项目中附加了多个属性,例如ListView.isCurrentItem可以用来判断一个条目是否是当前条目。在下面的例子中可以发现根委托项目可以使用ListView.isCurrentItem来直接访问该属性,而contactInfo对象必须使用wrapper.ListView.isCurrentItem来访问该属性。

ListView{

         width:180; height:200
         Component{
            id:contactsDelegate

            Rectangle{
            id:wrapper
            width:180
            height:contactInfo.height
            color:ListView.isCurrentItem?"black":"red"

            Text{
            id:contactInfo
            text:name+":"+number
            color:wrapper.ListView.isCurrentItem?"red":"black"
            }
            }
         }

       model:ContactModel{}
       delegate: contactsDelegate
       highlight:Rectangle{color:"lightsteelblue";radius: 5}
       focus:true;
     }

  

   

此例子中,委托作为ListView的子属性。可用ListView.isCurrentItem。在text中使用是必须加id是因为,isCurrentItem判断的是ListView的子项目,也就是Text的父项目。

 

2.2 GridView

     与ListView的概念及使用方法非常相似,不同之处在于将条目排列成网格。

     Rectangle{
     width:200;height:200

     Component{
     id:contactDelegate
     Item{
     width:180;height:40
     Column{
        Text{text:\'<b>Name:</b>\'+name}
        Text{text:\'<b>Number:</b>\'+number}
     }
     }
     }

     GridView{
       anchors.fill: parent
       cellWidth:100; cellHeight:100;
       model:ContactModel{}
       delegate: contactDelegate

     }
     }

  

 

 

2.3 PathView 

     与前两者最大的不同之处在于它是在一个路径(Path)上排列条目的。可以在一条曲线上排列。

2.4 WebView

      主要用来对网页内容进行渲染,只需为其指定一个URL即可。在使用该元素是需要首先导入QtWebKit模块。

 

以上是关于QML中的模型/视图 十二的主要内容,如果未能解决你的问题,请参考以下文章

如何通过单击适配器类中代码的项目中的删除按钮来删除列表视图中的项目后重新加载片段?

qml基础学习 模型视图

如何从QML中的GridView或ListView获取实例化的委托组件

如何在黑莓 10 级联 qml 中获取列表视图行数?

如何将 QPixmap 从 C++ 模型传递到 QML?

qml + 主细节