一、概述
qt5之后qml也可以被用于桌面程序开发,今天我就拿出qt demo中的一个qml示例程序进行分析。这个demo主要是展示了qml数据和展示分离的使用方式,qml只专注于快速高效的绘制界面,而数据存储、数据加工都交由qt来做(也可以认为是C++来实现复杂的逻辑),这样的话qml和qt关系就像是html和js的关系,以后使用qt我们也可以高效的开发出绚丽的桌面程序。
二、效果展示
如图1所示,数据展示使用了qml中的ListView控件,而数据存储使用的是QAbstractListModel。
图1 qml动态数据展示图
三、源码分析
1、main.cpp文件,添加定时器是为了动态添加数据,具体效果请看图1
int main(int argc, char ** argv) { QGuiApplication app(argc, argv); AnimalModel model; model.addAnimal(Animal("Wolf", "Medium")); model.addAnimal(Animal("Polar bear", "Large")); model.addAnimal(Animal("Quoll", "Small")); QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); QQmlContext *ctxt = view.rootContext(); ctxt->setContextProperty("myModel", &model); //![0] view.setSource(QUrl("qrc:view.qml")); view.show(); QTimer time; QObject::connect(&time, &QTimer::timeout, ctxt, [&model]{ model.addAnimal(Animal("Quoll", "Small")); }); time.start(1000); //qml嵌入QWidget方式 //QWidget * widget = QWidget::createWindowContainer(&view); //widget->show(); return app.exec(); }
2、头文件
1 //自定义动物结构体,包含类型和大小两个字段 2 class Animal 3 { 4 public: 5 Animal(const QString &type, const QString &size); 6 7 QString type1() const;//返回动物类型 8 QString size2() const;//返回动物大小 9 10 private: 11 QString m_type; 12 QString m_size; 13 }; 14 //自定义model,用于存储List数据 15 class AnimalModel : public QAbstractListModel 16 { 17 Q_OBJECT 18 public: 19 enum AnimalRoles { 20 TypeRole = Qt::UserRole + 1, 21 SizeRole 22 }; 23 24 AnimalModel(QObject *parent = 0); 25 26 void addAnimal(const Animal &animal);//新增一个动物 27 28 int rowCount(const QModelIndex & parent = QModelIndex()) const;//返回指定索引包含的行数 29 30 QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;//返回索引的指定数据类型 31 32 protected: 33 QHash<int, QByteArray> roleNames() const;//各字段名称 34 private: 35 QList<Animal> m_animals;//动物列表 36 };
3、实现文件
1 Animal::Animal(const QString &type, const QString &size) 2 : m_type(type), m_size(size) 3 { 4 } 5 6 QString Animal::type1() const 7 { 8 return m_type; 9 } 10 11 QString Animal::size2() const 12 { 13 return m_size; 14 } 15 16 AnimalModel::AnimalModel(QObject *parent) 17 : QAbstractListModel(parent) 18 { 19 } 20 21 void AnimalModel::addAnimal(const Animal &animal) 22 { 23 beginInsertRows(QModelIndex(), rowCount(), rowCount());//model底层插入数据时必须调用该接口 第二个和第三个参数标示插入的开始和结束行 24 m_animals << animal; 25 endInsertRows();//标示插入结束 26 } 27 28 int AnimalModel::rowCount(const QModelIndex & parent) const { 29 Q_UNUSED(parent); 30 return m_animals.count(); 31 } 32 33 QVariant AnimalModel::data(const QModelIndex & index, int role) const { 34 if (index.row() < 0 || index.row() >= m_animals.count()) 35 return QVariant(); 36 37 const Animal &animal = m_animals[index.row()]; 38 if (role == TypeRole) 39 return animal.type1(); 40 else if (role == SizeRole) 41 return animal.size2(); 42 return QVariant(); 43 } 44 45 QHash<int, QByteArray> AnimalModel::roleNames() const { 46 QHash<int, QByteArray> roles;//返回列名称 47 roles[TypeRole] = "type2"; 48 roles[SizeRole] = "size"; 49 return roles; 50 }
四、源码
源码路径:Examples\Qt-5.7\quick\models\abstractitemmodel