1

Let's define a in A.qml the following component:

Item {
    function test() { console.log("this is a test") }
}

And in B.qml we do the following:

A {
    function test2() { console.log("this is a second test") }
}

In C++ I create a QQuickView and set the source as B.qml. Now I try to invoke "test" and it fails with an error message that says that "test does not exist in B". If I invoke "test2" everything works as expected. If I change test2 for the following:

A {
    function test2() { test() }
}

It succeeds in calling test().

The question is, how do I call the test() function directly from C++ when it is defined the A.qml component?

Note: I´m using Qt 5.7.1

Federico
  • 576
  • 4
  • 20
  • Good question. I'm surprised that test() isn't in scope from C++, because in QML all inherited methods are visible – Mark Ch Oct 08 '17 at 21:38
  • If that is indeed the case, it is most likely a bug. – dtech Oct 08 '17 at 22:36
  • Possible duplicate of [Calling a QML function from C++](https://stackoverflow.com/questions/20000255/calling-a-qml-function-from-c) – eyllanesc Oct 09 '17 at 01:57
  • @eyllanesc I would say this question is not a dupe, because the questioner implies they already know how to use `QMetaObject::invokeMethod()`, but in this case of QML component inheritance it does not seem to work correctly – Mark Ch Oct 09 '17 at 06:00

1 Answers1

0

I have tried to replicate the problem you described using Qt 5.9.1 on Windows 7, and I cannot reproduce it. I am able to call both test() and test2() from C++.

Therefore if you want more help you will need to post more code to help reproduce the problem.

My code below...

A.qml

import QtQuick 2.7

Item {
    function test() { console.log("this is a test") }
}

B.qml

import QtQuick 2.7
import QtQuick.Controls 2.0

A {
    id: root
    function test2() { console.log("this is a second test") }

    Button {
        text: "click me"
        onClicked: {
            helper.invokeMethod(root, "test");
            helper.invokeMethod(root, "test2");
        }
    }
}

helper.h

#ifndef HELPER_H
#define HELPER_H

#include <QObject>

class Helper : public QObject
{
    Q_OBJECT
public:
    explicit Helper() { }

    Q_INVOKABLE void invokeMethod(QObject* obj, QString method){
         QMetaObject::invokeMethod(obj, method.toLatin1().constData());
    }

signals:

public slots:
};

#endif // HELPER_H

main.cpp

#include <QGuiApplication>
#include <QQmlContext>
#include <QQuickView>
#include "helper.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    Helper helper;

    QQuickView *view = new QQuickView;
    view->rootContext()->setContextProperty("helper", &helper);
    view->setSource(QUrl("qrc:/B.qml"));
    view->show();

    return app.exec();
}
Mark Ch
  • 2,840
  • 1
  • 19
  • 31