2012-02-29 16 views
21

Estoy tratando de hacer un pequeño programa con Qt. Tengo un main.cpp con el siguiente código:Accede a la función C++ desde QML

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

y tengo un archivo .qml:

import QtQuick 1.1 

Rectangle { 

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

Ahora, cuando hago clic en el MouseArea, el programa se cierra. Lo que quiero es que llame a la función reken_tijden_uit en el archivo main.cpp.

He buscado mucho en Google y he buscado en este sitio. Encontré un par de respuestas, pero no funcionó.

¿Qué código pongo donde puedo llamar a la función reken_tijden_uit en C++?

Gracias de antemano.


El archivo de cabecera es el siguiente:

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

y el archivo 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() 
     } 
    } 
} 

Y los errores son los siguientes:

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 

¿Qué hice mal?

+0

favor, compruebe el siguiente hilo de este que te pueden ayudar a http: // stackoverflow.com/questions/5709820/communication-between-c-and-qml – shofee

+0

hy lo he comprobado, pero no es exactamente lo que quiero ... quiero agregar un evento onclick al mousearea que llama a la función cpp. (en javascript es solo reken_tijden_uit(); entonces, ¿cómo funciona en C++ y qml ... – Mathlight

Respuesta

33

Para que se llame cualquier código C++ desde QML, debe residir dentro de un QObject.

Lo que necesita hacer es crear una clase descendiente QObject con su función, registrarla en QML, crear instancias en su QML y llamar a la función. Tenga en cuenta también que debe marcar su función con Q_INVOKABLE.

Código:

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

y dónde tengo que poner la primera pieza de código? – Mathlight

+0

Lo mejor, en un .cpp/.h adicional agregado a su proyecto. No se olvide de incluir .h en main.cpp antes de hacer qmlRegisterType – Koying

+0

bien, tengo un par de errores, voy a publicar una nueva respuesta para que quede claro cuál es el problema ... – Mathlight

0

Como alternativa a qmlRegisterType() en main.cpp, se también puede usar propiedades de contexto para hacer QO variables de bject disponibles en QML. (En caso de que no necesite crear diferentes instancias de su objeto con QML posterior).

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, a continuación, puede acceder al objeto desde cualquier parte del código con el nombre determinado en la segunda main.cpp.No hay declaraciones adicionales requeridos:

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

usted puede encontrar más información sobre QML < - posibilidades> C++ de comunicación aquí: https://v-play.net/cross-platform-development/how-to-expose-a-qt-cpp-class-with-signals-and-slots-to-qml

Cuestiones relacionadas