Reputation: 293
So I'm starting to get the hang of Qt's MOC system in C++, and have been using the Q_PROPERTY macro and associated functionality to get introspection on Qt inbuilt types. However I can't seem to find a way of defining properties for custom types.
For example, in the following code, I can use metaObjects to identify, read and write with the variable A, which is a member of TestParent, with the use of Q_PROPERTY and the two corresponding functions. However attempting to register anything of the custom type Child gives me the error
QObject::QObject(const QObject&) is private within this context
I understand that this is because Child inherits from QObject, but I would like to use Qt's properties system within the Child class too, which requires inheritance from QObject. Is there a correct way of implementing this?
class Child : public QObject
{
Q_OBJECT //Q_OBJECT macro required here for the MOC to use introspection
public:
explicit Child(QObject *parent = 0);
~Child();
};
class TestParent : public QObject
{
Q_OBJECT
Q_PROPERTY(int A READ A WRITE setA) //this works
Q_PROPERTY(Child child READ child WRITE setChild) //this doesn't
public:
explicit TestParent(QObject *parent = 0);
~TestParent();
void setA(int A) {_A = A;}
int A() const {return _A;}
void setChild(Child c) {_child = c;}
Child child() const {return _child;}
private:
int _A;
Child _child;
};
The constructors and destructors both TestParent and Child are implemented blank methods in the .cpp file
Thanks.
Upvotes: 2
Views: 5105
Reputation:
You need to implement assignment operator and copy constructor to use your Child property by-value (as in your code, not by-pointer from previous comment). If you'll use it by-pointer, don't forget to set parent to this property on creation (so you will not need directly destroy it)
So, this is example:
#pragma once
#include <QObject>
class Child : public QObject
{
Q_OBJECT
public:
Child() = default;
Child(const Child &other, QObject *parent = nullptr)
: QObject(parent)
{
Q_UNUSED(other);
}
public:
Child& operator =(const Child &other) {
Q_UNUSED(other);
return *this;
}
};
class TestParent : public QObject
{
Q_OBJECT
Q_PROPERTY(int a READ a WRITE setA NOTIFY aChanged)
Q_PROPERTY(Child child READ child WRITE setChild NOTIFY childChanged)
public:
TestParent() = default;
signals:
void aChanged();
void childChanged();
public:
void setA(const int &a) { _a = a; }
const int& a() const { return _a; }
void setChild(Child c) { _child = c; }
const Child& child() const { return _child; }
private:
int _a;
Child _child;
};
Upvotes: 0
Reputation: 293
Ah, got it now. Thanks Retired Ninja.
For others looking for this, it ends up being
class TestParent : public QObject
{
Q_OBJECT
Q_PROPERTY(Child * child READ child WRITE setChild)
public:
explicit TestParent(QObject *parent = 0);
~TestParent();
void setChild(Child *c) {_child = c;}
Child * child() const {return _child;}
private:
Child * _child;
};
But don't forget to initialise that pointer!
Upvotes: 1