Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Zip archive can be found here: http://ompldr.org/vOXJybw/qproperty.zip
- //////////////// A.cpp ////////////////
- #include "A.hpp"
- A::A(QString name)
- : mName(name) {}
- B* A::GetB(int i) {
- return mBs[i];
- }
- void A::SayName() {
- qDebug() << "A says its name: " << mName;
- }
- //////////////// A.hpp ////////////////
- #ifndef _A
- #define _A
- #include "B.hpp"
- #include <QtCore/QObject>
- #include <QtCore/QString>
- class A : public QObject {
- Q_OBJECT
- Q_PROPERTY(QString name READ GetName FINAL)
- public:
- A(QString name);
- // need a template here because in the real project
- // we inherit B
- template <typename T>
- void AddB(T* t) {
- mBs.append(t);
- t->SetA(this); // this is why we need forward declaration in B.hpp, not here
- }
- public slots:
- // I had a const QString& here, but since slots cannot return
- // references I have to copy the string :(
- QString GetName() { return mName; }
- B* GetB(int i);
- void SayName();
- private:
- QString mName;
- QList<B*> mBs;
- };
- #endif
- //////////////// B.cpp ////////////////
- #include "B.hpp"
- #include "A.hpp" // because we only forward-declared it in our header
- B::B(QString name)
- : mName(name),
- mA(0x0) {}
- void B::SetA(A* a) {
- mA = a;
- }
- void B::SayName() {
- qDebug() << "B says its name: " << mName;
- }
- void B::SayNameOfA() {
- if(mA != 0x0) {
- qDebug() << "B knows its A's name: " << mA->GetName();
- } else {
- qDebug() << "B does not have an A";
- }
- }
- A* B::GetA() {
- return mA;
- }
- QString B::GetName() {
- return mName;
- }
- //////////////// B.hpp ////////////////
- #ifndef _B
- #define _B
- #include <QtCore/QObject>
- #include <QtCore/QString>
- #include <QtCore/QDebug>
- // forward declare here, as we need B in the
- // template of A
- class A;
- class B : public QObject {
- Q_OBJECT
- Q_PROPERTY(QString name READ GetName FINAL)
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- // The problems are here:
- // - A is incomplete struct for MOC
- // - GetA() returns a pointer to A, not a copy of it
- // Q_PROPERTY(A a READ GetA)
- public:
- B(QString name);
- void SetA(A* a);
- public slots:
- A* GetA();
- QString GetName();
- void SayNameOfA();
- void SayName();
- private:
- QString mName;
- A* mA;
- };
- #endif
- //////////////// main.cpp ////////////////
- #include "A.hpp"
- #include "B.hpp"
- #include <QtCore/QCoreApplication>
- #include <QtScript/QScriptEngine>
- #include <QtScript/QScriptValue>
- #include <QtCore/QMetaType>
- int main(int argc, char** argv) {
- QCoreApplication app(argc, argv);
- QScriptEngine engine;
- // I create these on the stack as the "real project"
- // is using pointers in this case. Actually, these
- // objects are saved in boost::ptr_containers.
- A* a = new A("the A object");
- B* b = new B("the B object");
- a->AddB(b);
- // test it
- a->SayName();
- b->SayName();
- b->SayNameOfA();
- // test properties
- qDebug() << "Getting name property of A: " << a->property("name").toString();
- qDebug() << "Getting name property of B: " << b->property("name").toString();
- // test scripting
- QScriptValue aObj = engine.newQObject(a);
- engine.globalObject().setProperty("aObj", aObj);
- QScriptValue bObj = engine.newQObject(b);
- engine.globalObject().setProperty("bObj", bObj);
- // register A*
- // qRegisterMetaType<A*>("A*");
- QScriptValue result = engine.evaluate(
- "print(\"Script knows A's name: \" + aObj.name); \n"
- "print(\"Script knows B's name: \" + bObj.name); \n"
- "print(\"Script knows A's GetName(): \" + aObj.GetName()); \n"
- "print(\"Script knows B's GetName(): \" + bObj.GetName()); \n"
- "print(\"Script calls A::SayName...\"); \n"
- "aObj.SayName(); \n"
- "print(\"Trying to get B's A and its name: \" + bObj.GetA().GetName());");
- // Script Error in last line:
- // TypeError: cannot call GetA(): unknown return type 'A*' (register
- // the type qith qScriptRegisterMetaType()))"
- if(engine.hasUncaughtException()) {
- qDebug() << "Line" << engine.uncaughtExceptionLineNumber() << ": " <<
- result.toString();
- }
- }
- //////////////// Makefile ////////////////
- default: bake run
- bake: generate compile-moc compile
- generate:
- mkdir -p tmp/
- moc -o tmp/A.moc.hpp A.hpp
- moc -o tmp/B.moc.hpp B.hpp
- compile-moc:
- g++ -x c++ -c tmp/A.moc.hpp -o tmp/A.moc.hpp.cxx.o
- g++ -x c++ -c tmp/B.moc.hpp -o tmp/B.moc.hpp.cxx.o
- compile:
- g++ *.cpp tmp/*.cxx.o -lQtCore -lQtScript -oout
- run:
- ./out
- clean:
- [[ -d tmp ]] && rm -r tmp
- [[ -e out ]] && rm out
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement