Qt C++属性类型提供给 QML调用(三)
前言
前面兩篇文章已經(jīng)介紹了 QML 中如何調(diào)用 C++中的基礎(chǔ)屬性以及對象屬性,今天繼續(xù)來介紹另外一種:對象為列表類型的屬性調(diào)用方法。
概述
包含QObject派生類型列表的屬性也可以暴露給QML使用,但是,應(yīng)該使用QQmlListProperty類而不是QList< T >作為屬性類型。這是因?yàn)镼List不是QObject派生的類型,所以不能通過Qt元對象系統(tǒng)提供必要的QML屬性特性,例如,當(dāng)列表被修改時的信號通知,這就需要調(diào)用對象為列表類型的屬性。
QQmlListProperty是一個模板類,可以通過QList值方便地構(gòu)建。
正文
我們繼續(xù)在之前的工程中進(jìn)行修改,新建一個 School 類,示例如下:
//school.h #include <QQmlListProperty> #include <QObject> #include <QDebug> #include "student.h"class School : public QObject {Q_OBJECTQ_PROPERTY(QQmlListProperty<Student> students READ students)public:explicit School(QObject * parent = 0);QQmlListProperty<Student> students();void appendStudent(Student * stu);int studentCount() const;Student *student(int) const;void clearStudent();private:static void appendStudent(QQmlListProperty<Student> *list, Student * s);static int studentCount(QQmlListProperty<Student>*);static Student* student(QQmlListProperty<Student>*, int);static void clearStudent(QQmlListProperty<Student>*);private:QList<Student *> m_students; };//school.cpp School::School(QObject *parent) : QObject(parent) {}QQmlListProperty<Student> School::students() {return QQmlListProperty<Student>(this,this,&School::appendStudent,&School::studentCount,&School::student,&School::clearStudent); }void School::appendStudent(Student *stu) {m_students.append(stu); }int School::studentCount() const {return m_students.count(); }Student *School::student(int index) const {return m_students.at(index); }void School::clearStudent() {return m_students.clear(); }void School::appendStudent(QQmlListProperty<Student> *list, Student *s) {reinterpret_cast< School* >(list->data)->appendStudent(s); }int School::studentCount(QQmlListProperty<Student> *list) {return reinterpret_cast< School* >(list->data)->studentCount(); }Student *School::student(QQmlListProperty<Student> *list, int i) {return reinterpret_cast< School* >(list->data)->student(i); }void School::clearStudent(QQmlListProperty<Student> *list) {reinterpret_cast< School* >(list->data)->clearStudent(); }School 里面提供了一個students列表,并注冊成QQmlListProperty類型供 QML 調(diào)用。
然后 Student 類保持不變:
class Student : public QObject {Q_OBJECTQ_PROPERTY(QString name READ getName WRITE setName NOTIFY sigNameChanged)public:explicit Student(QObject *parent = nullptr);~Student(){}void setName(const QString & name){if(name != m_name){m_name = name;emit sigNameChanged(m_name);}}QString getName() const {return m_name;} signals:void sigNameChanged(QString name);private:QString m_name;};在 Main 函數(shù)中對類進(jìn)行注冊:
qmlRegisterType<Student>("Student", 1, 0, "Student"); qmlRegisterType<School>("School", 1, 0, "School");然后在 QML 中進(jìn)行調(diào)用:
import QtQuick 2.8 import Student 1.0 import School 1.0School{students:[Student{name:"xiaoming"},Student{name:"zhangsan"},Student{name:"lisi"}] }這里定義了一個School類型,其中包含三個 Student,每個 Student 設(shè)置其名稱。
然后我們回到 main 函數(shù)中 將 qml 定義好的對象打印出來看看效果:
QQmlEngine engine; QQmlComponent component(&engine, QUrl("qrc:main.qml")); School *school = qobject_cast<School *>(component.create());if(school){for (int i = 0; i < school->studentCount(); ++i)qWarning() << " " << school->student(i)->getName(); }運(yùn)行程序,輸出如下:
"xiaoming" "zhangsan" "lisi"本文中是試驗(yàn)從 QML 中創(chuàng)建列表對象,然后在C++中打印出創(chuàng)建好的列表,當(dāng)然也可以在 C++中創(chuàng)建好列表,然后在 QML 中進(jìn)行調(diào)用。使用方法都是一樣,這里就不再贅述。
需要注意的是,在 Qt 幫助文檔中,QQmlListProperty的使用方法如下:
class MessageBoard : public QObject {Q_OBJECTQ_PROPERTY(QQmlListProperty<Message> messages READ messages) public:QQmlListProperty<Message> messages();private:static void append_message(QQmlListProperty<Message> *list, Message *msg);QList<Message *> m_messages; };QQmlListProperty<Message> MessageBoard::messages() {return QQmlListProperty<Message>(this, 0, &MessageBoard::append_message); }void MessageBoard::append_message(QQmlListProperty<Message> *list, Message *msg) {MessageBoard *msgBoard = qobject_cast<MessageBoard *>(list->object);if (msg)msgBoard->m_messages.append(msg); }- 這里添加列表元素的時候只用到了一個靜態(tài)函數(shù)append_message,奇怪的是我用這種方法一直會報錯,編譯不通過,無奈之下用了第二種方法,將所有需要的靜態(tài)函數(shù)全部寫進(jìn)去了。其實(shí)該類的構(gòu)造函數(shù)有三個,如下:
我用第一個構(gòu)造函數(shù)的方式一直報錯,然而使用所有參數(shù)的形式就正常,目前還不知道是什么原因,先這樣吧。
代碼在這里
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Qt C++属性类型提供给 QML调用(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qt C++属性类型提供给 QML调用(
- 下一篇: Qt C++属性类型提供给 QML调用(