Home > database >  Qt QML-CPP expose class as Q_PROPERTY
Qt QML-CPP expose class as Q_PROPERTY

Time:09-08

Is it possible to expose class as Q_PROPERTY? (I know how to expose native variables.)

In my case, I want to handle chunk of data that change at the same time, and I want to render it at the same frame.

Is it possible?

CodePudding user response:

Generally speaking, yes you can. As long as your custom class uses the Q_OBJECT or Q_GADGET macros, you can use Q_PROPERTY on this custom type.

For better understanding, have a look on this documentation: https://wiki.qt.io/How_to_Use_a_Custom_Class_in_C++_Model_and_QML_View

CodePudding user response:

Let's say you are implementing wrappers for QDir and QFileInfo and that you have implemented both Dir and FileInfo as QObjects. Then to return the FileInfo in a method your code would look like this:

FileInfo* Dir::fileInfo(const QString& fileName) const {
    FileInfo* fileInfo = new FileInfo(fileName);
    QQmlEngine::setObjectOwnership(fileInfo, QQmlEngine::JavaScriptOwnership);
    return fileInfo;
}

What the above code snippet is doing is creating a new FileInfo QObject but if the reference count of this QObject falls to 0 then we're allowing the QML/JS engine privilege to garbage collect it when it needs to be. The code snippet doesn't show the qmlRegisterType (or their QML_ELEMENT equivalent) that you would need to register both FileInfo and Dir classes properly, but, I am assuming that you already know how to do this. Because it is a QObject the app can take a copy of this object and can inspect (i.e. reflection) all of its properties and methods at runtime. Intellisense is possible.

The above pattern would be similar to a property as well. I would probably do something like:

FileInfo* Dir::defaultFileInfo() {
    if (!m_FileInfo) {
        m_FileInfo = new FileInfo(this);
        QQmlEngine::setObjectOwnership(m_FileInfo, QQmlEngine::CppOwnership);
    }
    return m_FileInfo;
}

The above code snippet indicates that the parent class will control the creation and destruction of the request object and that there will be at most one instance created and subsequent access to the property will return the same instance.

As to Q_GADGET. Technically, I would only return a Q_GADGET where you know the entire lifecycle of the object, for instance, in a signal where you want to conveniently provide access to your class and methods. The advantage of this is there is no delegation to the QML/JS engine of your object, nor is there any type register or memory management. This is useful for exposing structures, but, the caveat, is that access to this class is limited to the duration of the signal handler and there is no access allowed beyond this. It is up to the app to copy out any values it needs from the class.

  • Related