【问题标题】:Access C++ function from QML从 QML 访问 C++ 函数
【发布时间】:2012-03-19 00:10:36
【问题描述】:

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

那么我做错了什么?

【问题讨论】:

  • 请查看以下帖子,这可能会对您有所帮助stackoverflow.com/questions/5709820/…
  • hy,我检查了它,但这不是我想要的……我想在调用 cpp 函数的鼠标区域中添加一个 onclick 事件。 (在 javascript 中它只是 reken_tijden_uit(); 那么它在 c++ 和 qml 中是如何工作的......

标签: c++ qt function qml


【解决方案1】:

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

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

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

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

【讨论】:

  • 有一个 [Qt 文档中的流程图] (doc.qt.io/qt-5/…) 有助于决定何时更好地使用 qmlRegisterTypes 方法以及何时使用 setContextProperty
【解决方案2】:

对于要从 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())
        }
    }
}

【讨论】:

  • 最好,在单独的 .cpp/.h 中添加到您的项目中。在执行 qmlRegisterType 之前不要忘记在 main.cpp 中包含 .h
  • 好吧,我有几个错误,我会发布一个新的答案,所以很清楚问题是什么......
  • 1) 你有两次“QScopedPointer...”。删除第一个 2) 将“qmlRegisterType...”移动到第二个“QScopedPointer...”之后,即在 main{} 内 3) 执行“console.log(myobject.reken_tijden_uit())”检查它可以工作(将出现在 qt creator 的控制台中)
  • 在 QML 中? IE。 onClicked: { console.debug(myobject.reken_tijden_uit()) }
  • 好吧,我仍然有错误,并将 console.log 放在 qml 中的 onClicked 上。错误如下: D:*\main.cpp:-1: In function 'int qMain(int, char**)': AND D:*\main.cpp:14: error: 'qmlRegisterType' was not declared在此范围内 AND D:*\main.cpp:14: 错误: '>' 标记之前的预期主表达式
猜你喜欢
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-30
  • 2013-12-04
相关资源
最近更新 更多