[SOLVED] How to call Javascript function OR Q_INVOKALBE on dynamically created QmlComponent



  • Hi.

    Im new to Qt and starting my first project. Target is to write a clean code by realizing the MVC pattern, where the business logic is C++ and GUI QtQuick. I read the articles and tutorials about C++ integration:

    http://qt-project.org/doc/qt-5/qml-extending-tutorial-index.html
    http://qt-project.org/doc/qt-5/qtqml-cppintegration-definetypes.html

    and watched some videos about the topic (https://www.youtube.com/watch?v=n3JJZRQG39o)

    But none them answers my question, which is not unusual in my opinion, how to call a Javascript function OR a C++ invokable on dynamically created instances.

    Here is my code:

    main.cpp
    @int main(int argc, char *argv[])
    {
    QGuiApplication app(argc, argv);
    qmlRegisterType<StartController>("Controller", 1, 0, "Start");
    qmlRegisterType<TestScreenController>("Controller", 1, 0, "TestScreen");
    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qrc:///qml/main.qml"));
    viewer.showExpanded();
    return app.exec();
    }
    @

    main.qml
    @
    import QtQuick 2.0
    import QtQuick.Controls 1.1

    StackView {
    id: mainStackView
    width: units.gu(38)
    height: units.gu(50)
    initialItem: Qt.resolvedUrl("content/Start.qml")
    }
    @

    Start.qml
    @
    import QtQuick 2.0
    import Controller 1.0
    Start {
    function gotoTestScreen(id) {
    var testScreen = Qt.createComponent("TestScreen.qml");
    mainStackView.push(testScreen);
    console.log ("Should start with " + id);
    testScreen.startWithID(id);
    }
    ...
    MouseArea {
    onClicked: gotoTestScreen(55);
    }
    @

    TestScreen.qml
    @
    import QtQuick 2.0
    import Controller 1.0;

    TestScreen {
    width:parent.width
    height: parent.height
    function startWithID(id) {
    console.log("start schedule from javascript");
    }
    }
    @

    TestScreenController (C++)
    @
    class TestScreenController : public QQuickItem
    {
    Q_OBJECT
    public:
    explicit TestScreenController(QQuickItem *parent = 0);
    Q_INVOKABLE void startWithID(QString id);
    };
    TestScreenController::TestScreenController(QQuickItem *parent) : QQuickItem(parent) {
    qDebug() << "instantiante TestScreenController";
    }

    void TestScreenController::startWithID(QString id) {
    qDebug() << "start schedule from C++";
    }
    @

    When the Javascript function gotoTestScreen() is called by pressing the button, the instance of TestScreenController is instantiated with it's GUI defined in TestScreen.qml. The variable testScreen is type of QmlComponent and could successfully be pushed to the StackView mainStackView. But neither the Javascript function OR the C++ Q_INVOKABLE could be called by testScreen.startWithID(id). The error message is:

    @
    qrc:///qml//content/Start.qml:20: TypeError: Property 'startWithID' of object QQmlComponent(0x110e31a60) is not a function
    @



  • Ok, I found it out by myself.
    I have to call the createObject() method on the QmlComponent instance.

    @
    var testScreen = Qt.createComponent("TestScreen.qml").createObject(parent);
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.