2

Here's what my main.cpp looks like:

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);
    QCoreApplication::addLibraryPath("./");

    QQuickView view;
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.setSource(QUrl("qrc:/myqml.qml"));
    view.show();

    return app.exec();
}

As you can see, it creates things from myqml. Well, myqml instantiates a C++ class MyClass.

How do I access this C++ methods from the object QQuickView view? For example, I'd like to do something of the type view.MyClassInstance.myMethod1()

4
  • show your .qml and MyClass Commented Feb 18, 2019 at 0:53
  • @eyllanesc I don't have them yet, it was just an example to see if it's possible to do what I want. MyClass is simply a child of QObject and myqml is simply MyClass{} Commented Feb 18, 2019 at 1:00
  • Where do you want to modify it, from C++ or QML? Commented Feb 18, 2019 at 1:00
  • @eyllanesc I want to modify (call methods) from C++ Commented Feb 18, 2019 at 1:01

1 Answer 1

3

You want to obtain an object created in QML by C++, here it does not matter if the target has a prototype created in C ++ or not. If you want this you must obtain the object through findChild since all the objects created in QML have a kinship relationship with the window.

main.cpp

#include <QtQuick>
#include <QtGui>

class MyClass: public QObject
{
    Q_OBJECT
public:
    using QObject::QObject;
    Q_INVOKABLE void invokable(){
        qDebug()<< "invokable";
    }
    Q_SLOT void slot(){
        qDebug()<< "slot";
    }
    void function(){
        qDebug()<< "function";
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    qmlRegisterType<MyClass>("foo", 1, 0, "MyClass");
    QGuiApplication app(argc, argv);

    QQuickView view;
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
    view.show();
    if(MyClass* myclass_instance = view.findChild<MyClass *>("myclass_instance")){
        myclass_instance->invokable();
        myclass_instance->slot();
        myclass_instance->function();
    }
    return app.exec();
}
#include "main.moc"

main.qml

import QtQuick 2.9
import foo 1.0

Rectangle {
    color: "salmon"
    width: 640
    height: 480
    MyClass{
        objectName: "myclass_instance"
    }
}

But this method has several drawbacks such as who manages the life cycle of the object is QML, not C ++ so the pointer could at some point point to an unreserved address. Another disadvantage is that there is a dependency of C++ to QML since if the objectName is changed in QML the code in C ++ would have to be changed.


Another approach is to create a helper class that is exported to QML with setContextProperty() and that interacts with the MyClass object.

main.cpp

#include <QtQuick>
#include <QtGui>

class MyClass: public QObject
{
    Q_OBJECT
public:
    using QObject::QObject;
    Q_INVOKABLE void invokable(){
        qDebug()<< "invokable";
    }
    Q_SLOT void slot(){
        qDebug()<< "slot";
    }
    void function(){
        qDebug()<< "function";
    }
};

class Helper: public QObject
{
    Q_OBJECT
public:
    using QObject::QObject;
    void call_function(){
        emit called();
    }
    Q_SIGNAL void called();
};

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    qmlRegisterType<MyClass>("foo", 1, 0, "MyClass");
    QGuiApplication app(argc, argv);

    Helper helper;

    QQuickView view;
    view.rootContext()->setContextProperty("helper", &helper);
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
    view.show();

    helper.call_function();
    return app.exec();
}
#include "main.moc"

main.qml

import QtQuick 2.9
import foo 1.0

Rectangle {
    color: "salmon"
    width: 640
    height: 480
    MyClass{
        id: myclass
    }
    Connections{
        target: helper
        onCalled:{
            myclass.invokable()
            myclass.slot()
        }
    }
}

The advantage of this method is that there is no dependence between the logic of C++ and QML, besides the life cycle does not generate problems since the myclass objects are not handled directly in QML. The disadvantage is that you write a little more code and you can only call the Q_INVOKABLE or Q_SLOT.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.