前言
前面已经介绍了三种关于 QML 调用 C++的属性方法,那么,今天继续介绍一种新的属性调用:分组属性。
分组属性
QML 调用 C++的分组属性,所谓的分组属性, 其实和第二篇文章介绍的调用类属性有些类似,写法有点类似下面这种形式:
Rectangle{
anchors.left: ...
anchors.leftMargin:...
}
这其实就是一个分组属性,这两个属性都是属于anchors组的。
但是这里需要注意的是,分组属性仅仅和对象属性的写法相同,但是其实际上有比较大的区别,因为分组属性是只读的,并且在构造时由父对象初始化为有效值。分组属性的子属性可以从QML修改,但分组属性对象本身永远不会改变,而对象类型属性可以随时从QML分配一个新的对象值。因此,分组属性对象的生命周期严格受C ++父实现控制,而对象类型属性可以通过QML代码自由创建和销毁。
那么如何去调用 C++的分组属性呢,来看看以下示例:
class StudentInfo : public QObject
{
Q_OBJECT
Q_PROPERTY(QString className READ getClass WRITE setClass)
Q_PROPERTY(QString address READ getAddress WRITE setAddress)
public:
explicit StudentInfo(QObject * parent = 0):QObject(parent) {}
void setClass(const QString & c){
if(c != m_class){
m_class = c;
}
}
QString getClass()const{return m_class;}
void setAddress(const QString & a){
if(a != m_address){
m_address = a;
}
}
QString getAddress()const{return m_address;}
private:
QString m_class;
QString m_address;
};
class Student : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ getName WRITE setName NOTIFY sigNameChanged)
Q_PROPERTY(StudentInfo* info READ getInfo)
public:
explicit Student(QObject *parent = nullptr):
QObject(parent)
{
m_info = new StudentInfo(this);
}
~Student(){}
void setName(const QString & name){
if(name != m_name){
m_name = name;
emit sigNameChanged(m_name);
}
}
QString getName() const {return m_name;}
StudentInfo * getInfo(){return m_info;}
signals:
void sigNameChanged(QString name);
private:
QString m_name;
StudentInfo * m_info = NULL;
};
然后在 Main 函数中注册:
qmlRegisterType<Student>("Student", 1, 0, "Student");
qmlRegisterType<StudentInfo>("StudentInfo", 1, 0, "StudentInfo");
在 QML 中进行调用:
Student{
info.className:"aaa"
info.address:"bbb"
}
然后我们会到 main函数中将信息输出:
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:main.qml"));
Student *student = qobject_cast<Student *>(component.create());
if(student){
qWarning() << " " << student->getInfo()->getAddress() << student->getInfo()->getClass() ;
}
编译运行,输出如下:
"bbb" "aaa"
其实用法很简单,就不再多说啦。
代码在这里