Reputation: 1517
I'm developing a Blackberry 10 mobile application using the BB Native SDK.
I need to call a QML function into my C++ class. I searched a lot on this but I only found the possibility to call C++ into QML not the inverse. You can check this: QML and C++ integration
Can anyone help me on this?
This is the QML code specifying the function that I need to call which add a marker into my mapview:
Container {
id: pinContainer
objectName: "pinContObject"
...
function addPin(lat, lon, name, address) {
var marker = pin.createObject();
marker.lat = lat;
marker.lon = lon;
...
}
}
Upvotes: 10
Views: 31069
Reputation: 514
there is another way using binding, when the value of some x value is changed on Cpp side and it is binded on the qml side, the onchange will be called on qml side. This solution is easier and more direct than connecting signal-to-signal as noticed here, however if you want to transfer data within the signal I recommend to use signal-signal connection
ex:
qml side
import com.drOmranConsulting.backend 1.0
BackEnd {
id: _backend
}
Page1Form {
objectName: "page1box"
/* property alias recchange: _backend.rec_x
signal rec_xChanged is transmitted from C++
when rec_x is newly set. To receive this signal
an alias is used in qml side to the value rec_x
the binding will be updated upon signal emitting
*/
property alias recXchange: _backend.rec_x
onRecXchangeChanged:
{
console.log("signal received")
console.log(" the x coordinate is changed on cpp side to " + _backend.getRecX() )
_rect.x=_backend.getRecX()
}
}
backend.h
signals:
void rec_xChanged(); /* cpp emits signal rec_xChanged */
/* when rec_x value has been changed */
/* in QML: value is aliased using */
/* property alias recchange: _backend.rec_x */
/* detecing signal at onRecchangeChanged */
in main.cpp
//Backend class Initialization
backend Backend;
qmlRegisterType<backend>("com.drOmranConsulting.backend",1,0,"BackEnd");
in backend.cpp
emit rec_xChanged();
Upvotes: 0
Reputation: 363
From Qt documentation:
http://qt-project.org/doc/qt-5/qtqml-cppintegration-interactqmlfromcpp.html#invoking-qml-methods
Calling QMetaObject::invokeMethod
one will call proper slot, no matter if it is defined in C++ or QML.
Upvotes: 3
Reputation: 828
MyItem.qml
import QtQuick 2.0
Item {
function myQmlFunction(msg) {
console.log("Got message:", msg)
return "some return value"
}
}
main.cpp
QQmlEngine engine;
QQmlComponent component(&engine, "MyItem.qml");
QObject *object = component.create();
QVariant returnedValue;
QVariant msg = "Hello from C++";
QMetaObject::invokeMethod(object, "myQmlFunction",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, msg));
qDebug() << "QML function returned:" << returnedValue.toString();
delete object;
This should works. Here i am calling a QML function from my C++ class.
Upvotes: 16
Reputation: 489
Thats what signals and slots are for. You can use the QML Connections for connecting arbitrary signals to arbitrary slots in QML.
http://qt-project.org/doc/qt-4.8/qml-connections.html
Container {
id: pinContainer
objectName: "pinContObject"
...
function addPin(lat, lon, name, address) {
var marker = pin.createObject();
marker.lat = lat;
marker.lon = lon;
...
}
Connections {
target: backend
onDoAddPin: {
addPin(latitude, longitude,name, address)
}
}
}
and in C++ backend, all you have to do is
class Backend: public QObject {
signals:
void doAddPin(float latitude, float longitude, QString name, QString address);
........
void callAddPinInQML(){
emit doAddPin( 12.34, 45.67, "hello", "world");
}
}
Upvotes: 18