When exactly to use a Q_PROPERTY ???
-
@JonB , @Axel-Spoerl
Hello !Could you please tell me the exact scenarios when I need to associate a data member with a Q_PROPERTY ?
Please refer to the below example.firstselfcodedqobjectclass.h
#ifndef FIRSTSELFCODEDQOBJECTCLASS_H #define FIRSTSELFCODEDQOBJECTCLASS_H #include <QObject> class FirstSelfCodedQObjectClass : public QObject { Q_OBJECT public: FirstSelfCodedQObjectClass(QObject *parent = nullptr); QString getName1() const; void setName1(const QString &name1); signals: void name1Changed(const QString& name1); private: QString m_name1; }; #endif // FIRSTSELFCODEDQOBJECTCLASS_H
firstselfcodedqobjectclass.cpp
#include "firstselfcodedqobjectclass.h" FirstSelfCodedQObjectClass::FirstSelfCodedQObjectClass(QObject *parent) : QObject(parent) {} QString FirstSelfCodedQObjectClass::getName1() const { return m_name1; } void FirstSelfCodedQObjectClass::setName1(const QString &name1) { if(m_name1 != name1) { m_name1 = name1; emit name1Changed(m_name1); } }
secondselfcodedqobjectclass.h
#ifndef SECONDSELFCODEDQOBJECTCLASS_H #define SECONDSELFCODEDQOBJECTCLASS_H #include <QObject> #include "firstselfcodedqobjectclass.h" class FirstSelfCodedQObjectClass; class SecondSelfCodedQObjectClass : public QObject { Q_OBJECT public: SecondSelfCodedQObjectClass(FirstSelfCodedQObjectClass *fs, QObject *parent = nullptr); QString getName2() const; void setName2(const QString &name2); public slots: void onName1Changed(const QString &name1); private: QString m_name2; }; #endif // SECONDSELFCODEDQOBJECTCLASS_H
secondselfcodedqobjectclass.cpp
#include "secondselfcodedqobjectclass.h" SecondSelfCodedQObjectClass::SecondSelfCodedQObjectClass(FirstSelfCodedQObjectClass *fs, QObject *parent) : QObject(parent) { QObject::connect(fs , &FirstSelfCodedQObjectClass::name1Changed , this , &SecondSelfCodedQObjectClass::onName1Changed); } QString SecondSelfCodedQObjectClass::getName2() const { return m_name2; } void SecondSelfCodedQObjectClass::setName2(const QString &name2) { if(m_name2 != name2) { m_name2 = name2; } } void SecondSelfCodedQObjectClass::onName1Changed(const QString &name1) { if(m_name2 != name1) { m_name2 = name1; } }
main.cpp
#include <QCoreApplication> #include <QDebug> #include "firstselfcodedqobjectclass.h" #include "secondselfcodedqobjectclass.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); FirstSelfCodedQObjectClass *f = new FirstSelfCodedQObjectClass; SecondSelfCodedQObjectClass *s = new SecondSelfCodedQObjectClass(f); f->setName1("Justin Bieber"); qDebug() << (f->getName1()); // Output Justin Bieber qDebug() << (s->getName2()); // Output Justin Bieber s->setName2("Julius Ceaser"); qDebug() << (f->getName1()); // Output Justin Bieber qDebug() << (s->getName2()); // Output Julius Ceaser return a.exec(); }
I had thought that the Q_PROPERTY is for using the signals-and-slots mechanism. But it turns out from the above example that we can use it without necessarily having any Q_PROPERTY.
This is the documentation I have referred to.
I'd greatly appreciate your help on this topic....
-
@Ash-V
Within Qt, we use the property system mainly for QML exposure.If you want to access a variable (e.g. with
int MyClass::myNumber() const
andvoid MyClass::setMyNumber(int number)
, you need to know these accessors at compile time. That means, whoever wants to seemyNumber()
or change it, needs to include the headers ofMyClass
.The Q_PROPERTY macro makes accessors to a variable available at runtime. A caller only needs to know that
MyClass
inherits fromQObject
. It can useQMetaObject
to find property names and e.g. useQObject::setProperty("myNumber", 42);
to modify it. -
@JonB , @Axel-Spoerl
Thanks, Axel, as well as Jon !I want to thank you both for being helpful !
-
@Axel-Spoerl
But Axel,
as you mentioned here,
the Q_PROPERTY isn't useful in the C++ part of Qt, right ?Suppose I have a class
class FirstClass : public QObject
and aclass SecondClass
wherein I want to use the accessors of FirstClass.Now, both ways (with or without using Q_PROPERTY) I definitely need to import the firstclass.hpp header file, I guess.
Because while referring the accessors of FirstClass, in SecondClass, I will refer them asFirstClass::<accessor>()
.Am I correct here Axel ???
Or there's something I'm missing here — any enhancements I can gain even in the C++ side of Qt via the usage of Q_PROPERTY ? -
@Ash-V said in When exactly to use a Q_PROPERTY ???:
any enhancements I can gain even in the C++ side of Qt via the usage of Q_PROPERTY ?
As already said there are none.
-
@Ash-V
You have:#include "firstselfcodedqobjectclass.h" class FirstSelfCodedQObjectClass; SecondSelfCodedQObjectClass(FirstSelfCodedQObjectClass *fs, QObject *parent = nullptr); ... SecondSelfCodedQObjectClass::SecondSelfCodedQObjectClass(FirstSelfCodedQObjectClass *fs, QObject *parent) : QObject(parent) { QObject::connect(fs , &FirstSelfCodedQObjectClass::name1Changed , this , &SecondSelfCodedQObjectClass::onName1Changed); }
While this works, it is probably not the most common pattern. It makes
SecondSelfCodedQObjectClass
have to know aboutFirstSelfCodedQObjectClass
and require it.In your other thread I suggested at https://forum.qt.io/topic/154984/expected-primary-expression-before-token/2
You are trying to do connections in constructor of
SecondSetCodedObjectClass
. This is usually not good, because you would have to pass an instance of signalling object to that constructor. Rather the usual place to do theconnect()
is (on the line after) where you callnew SecondSetCodedObjectClass
, which has visibility of that new slot object and the existing signal object (FirstSetCodedObjectClass *
) which you want to connect.I would likely change your
main()
to:FirstSelfCodedQObjectClass *f = new FirstSelfCodedQObjectClass; SecondSelfCodedQObjectClass *s = new SecondSelfCodedQObjectClass; QObject::connect(f , &FirstSelfCodedQObjectClass::name1Changed , s , &SecondSelfCodedQObjectClass::onName1Changed);
You should at least be aware of this pattern and understand it, it is more common.