从 QML 访问 C++ 函数
Posted
技术标签:
【中文标题】从 QML 访问 C++ 函数【英文标题】:Access C++ function from QML 【发布时间】:2012-02-29 13:46:19 【问题描述】:我正在尝试用 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
那么我做错了什么?
【问题讨论】:
请查看以下帖子,这可能会对您有所帮助***.com/questions/5709820/… hy,我检查了它,但这不是我想要的……我想在调用 cpp 函数的鼠标区域中添加一个 onclick 事件。 (在 javascript 中它只是 reken_tijden_uit(); 那么它在 c++ 和 qml 中是如何工作的...... 【参考方案1】:对于要从 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作为 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以上是关于从 QML 访问 C++ 函数的主要内容,如果未能解决你的问题,请参考以下文章