web-dev-qa-db-fra.com

Accéder à la fonction C ++ à partir de QML

J'essaye de faire un petit programme avec Qt. J'ai un main.cpp avec le code suivant:

#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;
}

et j'ai un .qml fichier:

import QtQuick 1.1

Rectangle {

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

Maintenant, quand je clique sur MouseArea, le programme se ferme. Ce que je veux, c'est qu'il appelle la fonction reken_tijden_uit dans le main.cpp fichier.

J'ai beaucoup googlé et cherché sur ce site pour. J'ai trouvé quelques réponses, mais je n'ai pas réussi à en trouver une.

Alors, quel code dois-je mettre où je peux appeler la fonction reken_tijden_uit en C++?

Merci d'avance.


Le fichier d'en-tête ressemble à ceci:

#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();
}

et le fichier 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: {
            myobject.reken_tijden_uit()
        }
    }
}

Et les erreurs sont les suivantes:

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

Alors qu'est-ce que j'ai fait de mal?

29
Mathlight

Pour que tout code C++ soit appelé à partir de QML, il doit résider dans un QObject.

Ce que vous devez faire est de créer une classe descendante QObject avec votre fonction, l'enregistrer dans QML, l'instancier dans votre QML et appeler la fonction. Notez également que vous devez marquer votre fonction avec 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())
        }
    }
}
41
Koying

Comme alternative à qmlRegisterType () dans main.cpp, vous pouvez également utiliser les propriétés de contexte pour rendre les variables QObject disponibles dans QML. (Dans le cas où vous n'avez pas besoin de créer différentes instances de votre objet avec QML plus tard).

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();

    // add single instance of your object to the QML context as a property
    // the object will be available in QML with name "myObject"
    MyObject* myObject = new MyObject(); 
    viewer.engine()->rootContext()->setContextProperty("myObject", myObject); 

    return app->exec();
}

En QML, vous pouvez ensuite accéder à l'objet depuis n'importe où dans votre code avec le nom donné spécifié dans main.cpp. Aucune déclaration supplémentaire requise:

MouseArea {
    anchors.fill: parent
    onClicked: {
        myObject.reken_tijden_uit()
    }
}

Vous pouvez trouver plus d'informations sur les possibilités de communication QML <-> C++ ici: https://v-play.net/cross-platform-development/how-to-expose-a-qt-cpp-class-with -signals-and-slots-to-qml

5
GDevT