现在的位置: 首页 > 综合 > 正文

QML Data Models 数据模型<一>

2013年08月14日 ⁄ 综合 ⁄ 共 2846字 ⁄ 字号 评论关闭

        在QML中,ListView、GridView、Repeater 需要数据模型提供数据,然后在显示。而如何显示则需要一个代理(delegate)来定义。模型可以是静态的,也能够动态添加删除或修改。delegate可以绑定到model的date roles 。例如:

 import Qt 4.7

 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
     }
 }


myModel 有两个roles ,type和age,在delegate中Text用到了这两个roles 

Text { text: type + ", " + age }

如果Text自己有type和age属性怎么办?这时我们可以用myModel.type、myModel.age来代替type和age,否则显示的将是Text的属性(property);


先面介绍几种常见的Model

QML Data Models

ListModel  roles通过ListElement属性定义

ListElement {
         name: "Apple"
         cost: 2.45
     }

XmlListModel  roles通过XmlRole属性定义

 XmlListModel {
      id: feedModel
      source: "http://rss.news.yahoo.com/rss/oceania"
      query: "/rss/channel/item"
      XmlRole { name: "title"; query: "title/string()" }
      XmlRole { name: "link"; query: "link/string()" }
      XmlRole { name: "description"; query: "description/string()" }
 }

VisualItemModel 可以用QML items ,比如Rectanle,Text作为模型。这种模型包括了数据和代理,所以不需要额外提供delegate

  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
  }

下面是本文的重点:C++ Data Models

通过C++为QML提供数据模型是很必要的,在数据量较大或需要实现处理的情况下尤为重要。

1.QSringList

2.QList<QObject*>


QStringList

QStringList  model 有一个modelData roles  。通过modelData提供数据给delegate

 ListView {
     width: 100; height: 100
     anchors.fill: parent

     model: myModel
     delegate: Rectangle {
         height: 25
         width: 100
         Text { text: modelData }
     }
 }
     QStringList dataList;
     dataList.append("Item 1");
     dataList.append("Item 2");
     dataList.append("Item 3");
     dataList.append("Item 4");

     QDeclarativeView view;
     QDeclarativeContext *ctxt = view.rootContext();
     ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));

但需要注意的是,当模型中数据改变时,即QStringList改变,不会自动同步到视图显示,需要我们再一次调用 QDeclarativeContext::setContextProperty()
,重新设定模型。

QList<QObject*>

学习过Qt的人都知道,QObject是很多类的基类,如果我们想让我们自己的类能够作为数据模型,使我们自己定义的属性可以在QML中访问,我们可以继承自QObject或其子类。其属性值(你可以通过Q_PROPERTY()宏来定义自己的属性)将作为roles,供delegate使用。

 class DataObject : public QObject
 {
     Q_OBJECT

     Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
     Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
     ...
 };

 int main(int argc, char ** argv)
 {
     QApplication app(argc, argv);

     QList<QObject*> dataList;
     dataList.append(new DataObject("Item 1", "red"));
     dataList.append(new DataObject("Item 2", "green"));
     dataList.append(new DataObject("Item 3", "blue"));
     dataList.append(new DataObject("Item 4", "yellow"));

     QDeclarativeView view;
     QDeclarativeContext *ctxt = view.rootContext();
     ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
     ...
 ListView {
     width: 100; height: 100
     anchors.fill: parent

     model: myModel
     delegate: Rectangle {
         height: 25
         width: 100
         color: model.modelData.color
         Text { text: name }
     }
 }

Note
the use of the fully qualified access to the color property. The properties of the object are not replicated in the model object, since
they are easily available via the modelData object.
(英文比我说的清楚)


抱歉!评论已关闭.