Access C++ function from QML
For any C++ code to be called from QML, it must reside inside a QObject
.
What you need to do is create a QObject
descended 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
.
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:
#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())
}
}
}
How to call c++ function from qml and change the lable text
You can find the documentation for integrating C++ and QML here: http://developer.blackberry.com/cascades/documentation/dev/integrating_cpp_qml/
As a cliff's notes:
In your HelloBB constructor you can expose the class to the QML like so:
qml->setContextProperty("HelloBB", this);
And then create a method in the C++ that you will be able to call from the QML. Remember, the method has to be marked as Q_INVOKABLE to be called from the QML.
Consider this:
In HelloBB.hpp:
public:
Q_INVOKABLE void test();
In HelloBB.cpp:
void HelloBB::test() {
qDebug() << "TEST";
}
In main.qml:
onClicked: {
HelloBB.test ()
}
Access an attribute c++ object from QML
You could do any of the following:
Add a public slot in API class:
API.cpp:
QString API::getUserName()
{
return user.getName();
}
main.qml:
Component.onCompleted: console.log( API.getUserName() )
Make User a Q_PROPERTY in API class:
API.h:
Q_PROPERTY( User* user READ user NOTIFY userChanged)
main.qml:
Component.onCompleted: console.log( API.user.getName() )
Register User with QML:
main.cpp:
qmlRegisterType<User>("MyUser", 1, 0, "MyUser");
main.qml:
Component.onCompleted: console.log( API.getUser().getName() )
To access QML component in C++ backend
You should use QObject::findChild()
to locate the object, and simply invoke the signal as you would a nominal method.
But there is a catch, as QQuickRectangle
itself is a private class, so it is not directly available for use in the C++ API. Also, it doesn't really have a clicked()
signal, not unless you implemented one yourself. And if you did, it won't be part of the C++ interface.
Also, there is no onClicked()
signal, the signal is clicked()
and onClicked:
is the handler hook.
However, you can still emit it using the Qt meta system, just use:
QObject * object = engine.rootObjects().at(0)->findChild<QObject *>("yourObjectName");
if (object) QMetaObject::invokeMethod(object, "clicked");
It will work even if the signal is implemented on the QML side, it will work even without casting to the concrete C++ type.
Now, if your object is not directly in the root object tree, you will not be able to find it and will have no choice but to pass a reference to it from the QML side to a C++ slot or invokable function.
QML instantiates C++ objects. How do I access their methods?
You want to obtain an object created in QML by C++, here it does not matter if the target has a prototype created in C ++ or not. If you want this you must obtain the object through findChild since all the objects created in QML have a kinship relationship with the window.
main.cpp
#include <QtQuick>
#include <QtGui>
class MyClass: public QObject
{
Q_OBJECT
public:
using QObject::QObject;
Q_INVOKABLE void invokable(){
qDebug()<< "invokable";
}
Q_SLOT void slot(){
qDebug()<< "slot";
}
void function(){
qDebug()<< "function";
}
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
qmlRegisterType<MyClass>("foo", 1, 0, "MyClass");
QGuiApplication app(argc, argv);
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
view.show();
if(MyClass* myclass_instance = view.findChild<MyClass *>("myclass_instance")){
myclass_instance->invokable();
myclass_instance->slot();
myclass_instance->function();
}
return app.exec();
}
#include "main.moc"
main.qml
import QtQuick 2.9
import foo 1.0
Rectangle {
color: "salmon"
width: 640
height: 480
MyClass{
objectName: "myclass_instance"
}
}
But this method has several drawbacks such as who manages the life cycle of the object is QML, not C ++ so the pointer could at some point point to an unreserved address. Another disadvantage is that there is a dependency of C++ to QML since if the objectName is changed in QML the code in C ++ would have to be changed.
Another approach is to create a helper class that is exported to QML with setContextProperty()
and that interacts with the MyClass object.
main.cpp
#include <QtQuick>
#include <QtGui>
class MyClass: public QObject
{
Q_OBJECT
public:
using QObject::QObject;
Q_INVOKABLE void invokable(){
qDebug()<< "invokable";
}
Q_SLOT void slot(){
qDebug()<< "slot";
}
void function(){
qDebug()<< "function";
}
};
class Helper: public QObject
{
Q_OBJECT
public:
using QObject::QObject;
void call_function(){
emit called();
}
Q_SIGNAL void called();
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
qmlRegisterType<MyClass>("foo", 1, 0, "MyClass");
QGuiApplication app(argc, argv);
Helper helper;
QQuickView view;
view.rootContext()->setContextProperty("helper", &helper);
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
view.show();
helper.call_function();
return app.exec();
}
#include "main.moc"
main.qml
import QtQuick 2.9
import foo 1.0
Rectangle {
color: "salmon"
width: 640
height: 480
MyClass{
id: myclass
}
Connections{
target: helper
onCalled:{
myclass.invokable()
myclass.slot()
}
}
}
The advantage of this method is that there is no dependence between the logic of C++ and QML, besides the life cycle does not generate problems since the myclass objects are not handled directly in QML. The disadvantage is that you write a little more code and you can only call the Q_INVOKABLE or Q_SLOT.
Can't access C++ QObject subclass methods from QML
DerivedClass
is missing Q_OBJECT
macro (it is not inherited!).
Then simply run qmake
again on your project & compile: it should work.
Related Topics
Convert String with Explicit Escape Sequence into Relative Character
Changing the Directory from Inside a C Program Under Windows Using System Command
Are Class Members Guaranteed to Be Contiguous in Memory
Is a Logical Right Shift by a Power of 2 Faster in Avr
What Happens When You Bit Shift Beyond the End of a Variable
How to Compare Two Time Stamp in Format "Month Date Hh:Mm:Ss" to Check +Ve or -Ve Value
Creating a New C++ Project in Eclipse Cdt with the Same Settings as Another Project
C++ Concept That Requires a Member Function with an Outputiterator as Parameter
Why Statements Cannot Appear at Namespace Scope
Why Is This Constexpr Static Member Function Not Seen as Constexpr When Called
"No Appropriate Default Constructor Available"--Why Is the Default Constructor Even Called
Checking for Underflow/Overflow in C++
Why Doesn't Delete Destroy Anything
Printf Rounding Behavior for Doubles
Critique My Non-Intrusive Heap Debugger
How to Get a Color Palette from an Image Using Opencv
What Is a Curly-Brace Enclosed List If Not an Intializer_List