c++qtfunctionqml

Access C++ function from QML


I'm trying to make a little program with Qt. I have a main.cpp with the following code:

#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"

Q_DECL_EXPORT int main(int argc, char *argv[])
{
    QScopedPointer<QApplication> app(createApplication(argc, argv));

    QmlApplicationViewer viewer;
    viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
    viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml"));
    viewer.showExpanded();

    return app->exec();
}

int reken_tijden_uit(){
    return true;
}

and I have a .qml file:

import QtQuick 1.1

Rectangle {
    width: 360
    height: 360
    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }
}

Now, when I click on the MouseArea, the program quits. What I want is that it calls the function reken_tijden_uit in the main.cpp file.

I've googled a lot, and searched on this site to. I've found a couple of answers, but I didn't get one working.

So what code do I put where so I can call the function reken_tijden_uit in C++?

Thanks in advance.


The header file looks like this:

#ifndef EIGEN_FUNCTION_HEADER_H
#define EIGEN_FUNCTION_HEADER_H

class MyObject : public QObject{
    Q_OBJECT
public:
    explicit MyObject (QObject* parent = 0) : QObject(parent) {}
    Q_INVOKABLE int reken_tijden_uit(){
    return 1;
    }
};

#endif // EIGEN_FUNCTION_HEADER_H

main.cpp:

#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"
#include "eigen_function_header.h"

QScopedPointer<QApplication> app(createApplication(argc, argv));

qmlRegisterType<MyObject>("com.myself", 1, 0, "MyObject");

Q_DECL_EXPORT int main(int argc, char *argv[])
{
    QScopedPointer<QApplication> app(createApplication(argc, argv));

    QmlApplicationViewer viewer;
    viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
    viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml"));
    viewer.showExpanded();

    return app->exec();
}

and the QML file:

import QtQuick 1.1
import com.myself 1.0

Rectangle {
    width: 360
    height: 360
    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }
    MyObject {
        id: myobject
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            myobject.reken_tijden_uit()
        }
    }
}

And the errors are as follow:

D:\*\main.cpp:6: error: 'argc' was not declared in this scope
D:\*\main.cpp:6: error: 'argv' was not declared in this scope
D:\*\main.cpp:8: error: expected constructor, destructor, or type conversion before '<' token

So what did I do wrong?


Solution

  • For any C++ code to be called from QML, it must reside inside a QObject.

    What you need to do is create a QObject descended class with your function, register it to QML, instantiate it in your QML and call the function. Note also that you have to mark your function with Q_INVOKABLE.

    Code:

    #ifndef EIGEN_FUNCTION_HEADER_H
    #define EIGEN_FUNCTION_HEADER_H
    
    #include <QObject>
    
    class MyObject : public QObject{
       Q_OBJECT
    public:
        explicit MyObject (QObject* parent = 0) : QObject(parent) {}
        Q_INVOKABLE int reken_tijden_uit(){
        return 1;
        }
    };
    
    #endif // EIGEN_FUNCTION_HEADER_H
    

    main.cpp:

    #include <QtGui/QApplication>
    #include <QtDeclarative>
    
    #include "qmlapplicationviewer.h"
    #include "eigen_function_header.h"
    
    Q_DECL_EXPORT int main(int argc, char *argv[])
    {
        QScopedPointer<QApplication> app(createApplication(argc, argv));
        qmlRegisterType<MyObject>("com.myself", 1, 0, "MyObject");
    
        QmlApplicationViewer viewer;
        viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
        viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml"));
        viewer.showExpanded();
    
        return app->exec();
    }
    

    QML:

    import QtQuick 1.1
    import com.myself 1.0
    
    Rectangle {
    
        width: 360
        height: 360
        Text {
            text: qsTr("Hello World")
            anchors.centerIn: parent
        }
        MyObject {
           id: myobject
        }
    
        MouseArea {
            anchors.fill: parent
            onClicked: {
                console.log(myobject.reken_tijden_uit())
            }
        }
    }