Łukasz Przeniosło
Łukasz Przeniosło

Reputation: 2959

Pass whole QAbstractTableModel to QML

I have subclassed the QAbstractTableModel. Now I would like to pass to to the QML side. All examples I found expose the override methods of the class using Q_INVOKABLE, ie data or setData. Can the whole QAbstractTableModel object be passed as Q_INVOKABLE? If yes, how to do that exactly?

Upvotes: 1

Views: 658

Answers (2)

christian
christian

Reputation: 11

It is not safe to pass pointers from C++ to Qml via Q_INVOKABLE as the Javascript garbage collecter will try to delete those objects from QML even though they are supposed to be owned by C++. Instead, you should pass your objects (pointers) as properties using Q_PROPERTY macro.

Upvotes: 0

talamaki
talamaki

Reputation: 5482

Q_INVOKABLE is meant for exposing methods of QObject derived types to QML. You can use Qt property system for exposing your QAbstractTableModel from your "global object" which you have made available to QML through QML context (as you commented under your question).

You can read from the documentation more about exposing Attributes of C++ Types to QML.

MyTableModel deriving from QAbstractTableModel:

class MyTableModel : public QAbstractTableModel
{
    Q_OBJECT
};

MyGlobalObject exposing MyTableModel member variable through the property system:

class MyGlobalObject : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QAbstractTableModel* myTableModel READ myTableModel CONSTANT)
public:
    MyGlobalObject(QObject *parent = nullptr) : QObject(parent), m_myTableModel(new MyTableModel) { }
    MyTableModel *myTableModel() { return m_myTableModel.data(); }
private:
    QScopedPointer<MyTableModel> m_myTableModel;
};

MyGlobalObject instance set as a context property in main:

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    MyGlobalObject model;
    engine.rootContext()->setContextProperty("myGlobalObject", &model);
}

MyTableModel used as model for QML TableView:

import QtQuick 2.12

TableView {
    model: myGlobalObject.myTableModel
}

Upvotes: 3

Related Questions