一、概述
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 QAbstractListModel16 {17 Q_OBJECT18 public:19 enum AnimalRoles {20 TypeRole = Qt::UserRole + 1,21 SizeRole22 };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 QHashroleNames() const;//各字段名称34 private:35 QList 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() const12 {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 QHashAnimalModel::roleNames() const {46 QHash roles;//返回列名称47 roles[TypeRole] = "type2";48 roles[SizeRole] = "size";49 return roles;50 }
四、源码
源码路径:Examples\Qt-5.7\quick\models\abstractitemmodel