从 QML 访问 C++ 函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9500280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:54:06  来源:igfitidea点击:

Access C++ function from QML

c++qtfunctionqml

提问by Mathlight

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

我正在尝试用 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;
}

and I have a .qmlfile:

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

Now, when I click on the MouseArea, the program quits. What I want is that it calls the function reken_tijden_uitin the main.cppfile.

现在,当我单击 时MouseArea,程序退出。我想的是,它调用函数reken_tijden_uitmain.cpp的文件。

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_uitin C++?

那么我应该把什么代码放在哪里,以便我可以reken_tijden_uit在 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:

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:

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

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?

那么我做错了什么?

回答by Chris Browet

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

对于要从​​ QML 调用的任何 C++ 代码,它必须驻留在QObject.

What you need to do is create a QObjectdescended 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.

您需要做的是QObject使用您的函数创建一个后代类,将其注册到 QML,在您的 QML 中实例化它并调用该函数。另请注意,您必须用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:

主.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:

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

回答by GDevT

As an alternative to qmlRegisterType()in main.cpp, you can also use context properties to make QObject variables available in QML. (In case you don't require to create different instances of your object with later QML).

作为main.cpp 中qmlRegisterType()的替代方法,您还可以使用上下文属性使 QObject 变量在 QML 中可用。(如果您不需要使用更高版本的 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();
}

In QML, you can then access the object from anywhere in your code with the given name specified in main.cpp. No additional declarations required:

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

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

You can find more information on QML<->C++ communication possibilities here: https://v-play.net/cross-platform-development/how-to-expose-a-qt-cpp-class-with-signals-and-slots-to-qml

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