从QML访问C++函数

Access C++ function from QML

本文关键字:函数 C++ 访问 QML      更新时间:2023-10-16

我正在尝试用Qt制作一个小程序。我有一个main.cpp,代码如下:

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

我有一个.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();
    }
}
}

现在,当我点击MouseArea时,程序将退出。我想要的是它调用main.cpp文件中的函数reken_tijden_uit

我在谷歌上搜索了很多,并在这个网站上搜索了。我找到了几个答案,但我没有找到一个。

那么,我应该把什么代码放在哪里,这样我就可以在C++中调用函数reken_tijden_uit了?

提前谢谢。


头文件如下所示:

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

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

错误如下:

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

那么我做错了什么?

对于要从QML调用的任何C++代码,它必须位于QObject中。

您需要做的是用您的函数创建一个QObject派生类,将其注册到QML,在QML中实例化它并调用该函数。还要注意,您必须使用Q_INVOKABLE标记您的函数。

代码:

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

作为main.cpp中qmlRegisterType()的替代方案,您还可以使用上下文属性使QML中的QObject变量可用。(如果您不需要在以后的QML中创建对象的不同实例)。

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

在QML中,您可以使用main.cpp中指定的给定名称从代码中的任何位置访问对象。无需额外声明:

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

您可以在QML<->上找到更多信息这里有C++通信的可能性:https://v-play.net/cross-platform-development/how-to-expose-a-qt-cpp-class-with-signals-and-slots-to-qml