Qt: Q_PROPERTY with pointer and forward declaration for QtScript access

Problem

I am doing a project using Q_OBJECT and Q_PROPERTY to access some objects from scripts. I have two problems:

  • creating classes that use forward declarations written by a script
  • returns property as a pointer

Explanation

1. Why do I need a declaration?

Class B receives the forward declaration in A because A needs a full B-type header because of the patterns. B only needs an incomplete type (A *) in the header, so a valid declaration is valid.

2. Why return a pointer?

We cannot return a copy, since we need access to the actual object in the script. We cannot return the link, since Qt does not allow slots to return links - their type will be ignored, they will return void *.

the code

To complete the code download on pastebin or in a ZIP archive or as a ZIP archive, the minimum example is available for testing / playback: I need to separate the files for direct declaration and for MOC. I added a Makefile to test it. Making prints: g ++, moc, Qt.

Important details

class A; // forward declaration necessary, see explanation above

class B : public QObject {
    Q_OBJECT
    Q_PROPERTY(A a READ GetA) // <-- ERROR HERE
    // ...

public slots:
    A* GetA() { 
        return mA; 
    }

private:
    A* mA;
    // ...
}

The error line in the script:

print(bObj.GetA().GetName());

Compilation error

This error disappears when I notice Q_PROPERTY above.

tmp/B.moc.hpp:95:51: error: invalid use of incomplete typestruct A’
tmp/../B.hpp:10:7: error: forward declaration ofstruct A’

Script exception

When you leave Q_PROPERTY and call the GetA () method as a slot from a script, I get the following exception:

Line 7: "TypeError: cannot call GetA(): unknown return type `A*' 
        (register the type with qScriptRegisterMetaType())"

A * qRegisterMetaType<A*>("A*"); :

Line 7: "TypeError: Result of expression 'bObj.GetA().GetName' 
        [undefined] is not a function." 

, GetA() A - , script . GetA() QVariant(A*), - ?

:

  • - Q_PROPERTY ?
  • (, , , "" script operator., - )
  • - QVariant (A *) A QtScript?
+5
1
  • A, A*, .
  • QScriptValue. . :

    class A; // forward declaration necessary, see explanation above
    
    class B : public QObject
    {
        Q_OBJECT
    
        // Using QScriptValue, made from A instead of A to allow script work correctly with an object
        Q_PROPERTY(QScriptValue a READ GetA) 
    
    public slots:
        QScriptValue GetA() {
            //making QScriptValue from A. Type conversion in C style only due to limitation of incomplete type
            //In real app it beter to put defenition of this slot after A defenition
            return static_cast<QScriptEngine*>(parent())->newQObject((QObject*)mA);
        }
    
    private:
        A* mA;
        // ...
    public:
        //I decided my object will be a child of scriptEngine, but you can take a pointer to it in some other way
        B(QScriptEngine * parent);
    };
    
    class A: public QObject
    {
        Q_OBJECT
    public slots:
        QString GetName() const {return "a name";}
    public:
        A(QScriptEngine*parent):QObject(parent){}
    
    };
    
    B::B(QScriptEngine *parent):QObject(parent), mA(new A(parent)){}
    
+6

All Articles