Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Emit signals from javascript to qml

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?

like image 223
aleks_misyuk Avatar asked Jan 02 '12 00:01

aleks_misyuk


People also ask

How do you emit a signal in QML?

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.

Does QML support JavaScript?

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.

Is QML same as 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.


2 Answers

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
like image 163
Peace Makes Plenty Avatar answered Oct 12 '22 19:10

Peace Makes Plenty


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();
...
like image 34
aleks_misyuk Avatar answered Oct 12 '22 18:10

aleks_misyuk