I want to emit signal from javascript-file and receive it in qml-file (To find when time-consuming operation will finished).
How can I do it?
A signal is automatically emitted when the value of a QML property changes. This type of signal is a property change signal and signal handlers for these signals are written in the form on<Property>Changed, where <Property> is the name of the property, with the first letter capitalized.
QML has a deep JavaScript integration, and allows signal handlers and methods to be defined in JavaScript. Another core feature of QML is the ability to specify and enforce relationships between object properties using property bindings, which are also defined using JavaScript.
QML is used in the Qt framework only. Javascript is an imperative language. Javascript is a very popular language used in many different places, for example embeddded in HTML sites or as part of node.
Neither Alex's nore Raja's solutions really answer the question. Alex's consists in calling directly from the javascript code the QML slot method, and Raja's consist in setting the value of a property of a QML object from the Javascript code. Both approaches negate the main advantage of the signal/slot mechanism which is that the signalling object does not need to know of the slot.
An approach closer to the spirit of the signal/slot mechanism is described in this blog post (not mine). It consists, within the javascript file, of creating a QML object (via the Qt.createQmlObject()
function) the sole function of which is to contain the javascript's object signals. Signals are emitted from javascript through calling the internal QML objects signal (e.g. internalQmlObject.signalName()
), and the javascript object signal can be connected in QML to QML slots with the usual connect
mechanism via javascriptObject.internalQmlObject.signalName.connect(receiver.slotName)
.
An example adapted from the blog post is below:
javascript_object.js:
var internalQmlObject = Qt.createQmlObject('import QtQuick 2.0; QtObject { signal someSignal(int value) }', Qt.application, 'InternalQmlObject');
function doSomething() {
internalQmlObject.someSignal(42);
}
test.qml:
import QtQuick 2.0
import 'javascript_object.js' as JavascriptObject
Rectangle {
Rectangle {
id: someComponent
function someSlot(v) {
console.log("Signal received " + v);
}
}
Component.onCompleted: {
JavascriptObject.internalQmlObject.someSignal.connect(someComponent.someSlot);
JavascriptObject.doSomething();
}
}
On execution it gives the following:
% qmlscene test.qml
Signal received 42
Thank you, @RajaVarma.
I found solution for myself.
In qml-file: create element Item (my loginItem) which contains function that plays the role of slot. For example (I need to know when handle login event):
import "scripts/auth.js" as Auth
...
Item {
id: loginItem
// Send himself to javascript module named Auth
Component.onCompleted: {
Auth.setLoginItem(loginItem);
}
// "Slot" function
function logged() {
console.debug("Login successfully");
// Do something
...
}
}
In js-file: create receiver for loginItem and use it.
var loginItem;
function setLoginItem(tempLoginItem) {
loginItem = tempLoginItem;
}
...
// Emit "signal"
loginItem.logged();
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With