一、效果展示
如图1所示,是一个ListView窗口,自定义了文本内容和项背景色。
图1 ListView
二、源码分析
代码比较简单,主要使用了QQmlContext类的setContextProperty方法,在当前context上下文中新增名字为name的属性,并为其赋值,该属性可以在qml系统中使用,注册代码如下,也是该示例的main函数
1 int main(int argc, char ** argv) 2 { 3 QGuiApplication app(argc, argv); 4 5 QList<QObject*> dataList; 6 dataList.append(new DataObject("Item 1", "red")); 7 dataList.append(new DataObject("Item 2", "green")); 8 dataList.append(new DataObject("Item 3", "blue")); 9 dataList.append(new DataObject("Item 4", "yellow")); 10 11 QQuickView view; 12 view.setResizeMode(QQuickView::SizeRootObjectToView); 13 QQmlContext *ctxt = view.rootContext(); 14 ctxt->setContextProperty("myModel1", QVariant::fromValue(dataList));//将数据设置到myModel属性中 15 //![0] 16 17 view.setSource(QUrl("qrc:view.qml")); 18 view.show(); 19 20 return app.exec(); 21 }
DataObject为自定义对象,继承自QObject类,如果自定义的C++类需要注册到qml系统则必须继承自QObject,并且需要声明Q_OBJECT宏。DataObject头文件声明如下,主要作用是自定义了name和color两个属性,并为其添加了set和get接口,并使用Q_PROPERTY宏将其注册到qml系统中。
1 class DataObject : public QObject 2 { 3 Q_OBJECT 4 5 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)//注册属性到qml系统 6 Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged) 7 //![0] 8 9 public: 10 DataObject(QObject *parent=0); 11 DataObject(const QString &name, const QString &color, QObject *parent=0); 12 13 //属性get和set方法 14 QString name() const; 15 void setName(const QString &name); 16 17 //属性get和set方法 18 QString color() const; 19 void setColor(const QString &color); 20 21 signals: 22 void nameChanged(); 23 void colorChanged(); 24 25 private: 26 QString m_name; 27 QString m_color; 28 //![1] 29 };
使用setContextProperty接口注册后属性可以直接被qml系统使用,具体代码如下
1 ListView { 2 100; height: 100 3 4 model: myModel1 5 delegate: Rectangle { 6 height: 25 7 parent.width 8 color: model.modelData.color//或者modelData.color 不能像name一样直接使用属性名称 因为color值和color属性重名 9 Text { text: name }//自定义DataObject结构中 使用Q_PROPERTY属性注册的属性名 10 } 11 }
在ListView控件中,我们指定了model的数据源为我们注册的属性,在ListView的绘制代理中我们可以直接访问我们注册的自定义类DataObject,访问方式是直接访问属性名称,就想上述代码第9行那样,第8行代码之所以加上作用于限定是因为属性名color重复了,当直接访问属性名称时,其实就等同于访问属性的get方法,设置属性时就等同于访问属性的set方法。
这篇示例代码在Qt5.7.0_vs2013ExamplesQt-5.7quickmodelsobjectlistmodel目录下。我使用的qt5.6.1-1版本,该版本为自行编译版本,编译参考:msvc2013编译qt5.6源码