1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
5\page qtqml-syntax-signals.html
7\title Signal and Handler Event System
8\brief the event system in QML
10Application and user interface components need to communicate with each other. For
11example, a button needs to know that the user has clicked on it.
12The button may change colors to indicate its state or perform some logic. As
13well, application needs to know whether the user is clicking the button. The
14application may need to relay this clicking event to other applications.
16QML has a signal and handler mechanism, where the \e signal is the event
17and the signal is responded to through a \e {signal handler}. When a signal
18is emitted, the corresponding signal handler is invoked. Placing logic such as
19a script or other operations in the handler allows the component to respond to
22\target qml-signals-and-handlers
23\section1 Receiving signals with signal handlers
25To receive a notification when a particular signal is emitted for a particular
26object, the object definition should declare a signal handler named
27\e on<Signal>, where \e <Signal> is the name of the signal, with the first
28letter capitalized. The signal handler should contain the JavaScript code to be
29executed when the signal handler is invoked.
31For example, the \l [QtQuickControls]{Button} type from the
32\l{Qt Quick Controls} module has a \c clicked signal, which
33is emitted whenever the button is clicked. In this case, the signal handler for
34receiving this signal should be \c onClicked. In the example below, whenever
35the button is clicked, the \c onClicked handler is invoked, applying a random
36color to the parent \l Rectangle:
40import QtQuick.Controls
44 width: 250; height: 250
47 anchors.bottom: parent.bottom
48 anchors.horizontalCenter: parent.horizontalCenter
51 rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
57\section2 Property change signal handlers
59A signal is automatically emitted when the value of a QML property changes.
60This type of signal is a \e {property change signal} and signal handlers for
61these signals are written in the form \e on<Property>Changed, where
62\e <Property> is the name of the property, with the first letter capitalized.
64For example, the \l MouseArea type has a \l {MouseArea::pressed}{pressed} property.
65To receive a notification whenever this property changes, write a signal handler
66named \c onPressedChanged:
73 width: 100; height: 100
76 onPressedChanged: console.log("taphandler pressed?", pressed)
81Even though the \l TapHandler documentation does not document a signal handler
82named \c onPressedChanged, the signal is implicitly provided by the fact that
83the \c pressed property exists.
85\section2 Signal parameters
87Signals might have parameters. To access those, you should assign a function to the handler. Both
88arrow functions and anonymous functions work.
90For the following examples, consider a Status component with an errorOccurred signal (see
91\l{Adding signals to custom QML types} for more information about how signals can be added to
100 signal errorOccurred(message: string, line: int, column: int)
106 onErrorOccurred: (mgs, line, col) => console.log(`${line}:${col}: ${msg}`)
110\note The names of the formal parameters in the function do not have to match those in the
113If you do not need to handle all parameters, it is possible to omit trailing ones:
116 onErrorOccurred: function (message) { console.log(message) }
120It is not possible to leave out leading parameters you are interested in, however you can use some
121placeholder name to indicate to readers that they are not important:
124 onErrorOccurred: (_, _, col) => console.log(`Error happened at column ${col}`)
128\note Instead of using a function, it is possible, but discouraged, to use a plain code block. In
129that case all signal parameters get injected into the scope of the block. However, this can make
130code difficult to read as it's unclear where the parameters come from, and results in slower
131lookups in the QML engine. Injecting parameters in this way is deprecated, and will cause runtime
132warnings if the parameter is actually used.
134\section2 Using the Connections type
136In some cases it may be desirable to access a signal outside of the object that
137emits it. For these purposes, the \c QtQuick module provides the \l Connections
138type for connecting to signals of arbitrary objects. A \l Connections object
139can receive any signal from its specified \l {Connections::target}{target}.
141For example, the \c onClicked handler in the earlier example could have been
142received by the root \l Rectangle instead, by placing the \c onClicked handler
143in a \l Connections object that has its \l {Connections::target}{target} set to
148import QtQuick.Controls
152 width: 250; height: 250
156 anchors.bottom: parent.bottom
157 anchors.horizontalCenter: parent.horizontalCenter
158 text: "Change color!"
163 function onClicked() {
164 rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
171\section2 Attached signal handlers
173An \l {Attached Properties and Attached Signal Handlers}{attached signal handler}
174receives a signal from an \e {attaching type} rather than the object within which
175the handler is declared.
177For example, \l{Component::completed}{Component.onCompleted} is an attached
178signal handler. It is often used to execute some JavaScript code when its
179creation process is complete. Here is an example:
185 width: 200; height: 200
186 color: Qt.rgba(Qt.random(), Qt.random(), Qt.random(), 1)
188 Component.onCompleted: {
189 console.log("The rectangle's color is", color)
194The \c onCompleted handler is not responding to a \c completed signal from
195the \l Rectangle type. Instead, an object of the \c Component \e{attaching type}
196with a \c completed signal has automatically been \e attached to the \l Rectangle
197object by the QML engine. The engine emits this signal when the Rectangle object is
198created, thus triggering the \c Component.onCompleted signal handler.
200Attached signal handlers allow objects to be notified of particular signals that are
201significant to each individual object. If there was no \c Component.onCompleted
202attached signal handler, for example, an object could not receive this notification
203without registering for some special signal from some special object.
204The \e {attached signal handler} mechanism enables objects to receive particular
205signals without extra code.
207See \l {Attached properties and attached signal handlers} for more information on
208attached signal handlers.
210\section1 Adding signals to custom QML types
212Signals can be added to custom QML types through the \c signal keyword.
214The syntax for defining a new signal is:
216\tt{signal <name>[([<type> <parameter name>[, ...]])]}
218A signal is emitted by invoking the signal as a method.
220For example, the code below is defined in a file named \c SquareButton.qml. The
221root \l Rectangle object has an \c activated signal, which is emitted whenever the
222child \l TapHandler is \c tapped. In this particular example the activated signal
223is emitted with the x and y coordinates of the mouse click:
232 signal activated(real xPosition, real yPosition)
233 property point mouseXY
234 property int side: 100
235 width: side; height: side
239 onTapped: root.activated(root.mouseXY.x, root.mouseXY.y)
240 onPressedChanged: root.mouseXY = handler.point.position
245Now any objects of the \c SquareButton can connect to the \c activated signal using an \c onActivated signal handler:
250 onActivated: (xPosition, yPosition)=> console.log("Activated at " + xPosition + "," + yPosition)
254See \l {Signal Attributes} for more details on writing signals for custom QML types.
257\target qml-connect-signals-to-method
258\section1 Connecting signals to methods and signals
260Signal objects have a \c connect() method to a connect a signal either to a
261method or another signal. When a signal is connected to a method, the method is
262automatically invoked whenever the signal is emitted. This mechanism enables a
263signal to be received by a method instead of a signal handler.
265Below, the \c messageReceived signal is connected to three methods using the \c connect() method:
273 signal messageReceived(string person, string notice)
275 Component.onCompleted: {
276 relay.messageReceived.connect(sendToPost)
277 relay.messageReceived.connect(sendToTelegraph)
278 relay.messageReceived.connect(sendToEmail)
279 relay.messageReceived("Tom", "Happy Birthday")
282 function sendToPost(person, notice) {
283 console.log("Sending to post: " + person + ", " + notice)
285 function sendToTelegraph(person, notice) {
286 console.log("Sending to telegraph: " + person + ", " + notice)
288 function sendToEmail(person, notice) {
289 console.log("Sending to email: " + person + ", " + notice)
294In many cases it is sufficient to receive signals through signal handlers
295rather than using the connect() function. However, using the \c connect
296method allows a signal to be received by multiple methods as shown earlier,
297which would not be possible with signal handlers as they must be uniquely
298named. Also, the \c connect method is useful when connecting signals to
299\l {Dynamic QML Object Creation from JavaScript}{dynamically created objects}.
301There is a corresponding \c disconnect() method for removing connected signals:
308 function removeTelegraphSignal() {
309 relay.messageReceived.disconnect(sendToTelegraph)
314\section3 Signal to signal connect
316By connecting signals to other signals, the \c connect() method can form different
324 width: 100; height: 100
327 onSend: console.log("Send clicked")
332 onTapped: console.log("Mouse clicked")
335 Component.onCompleted: {
336 mousearea.tapped.connect(send)
342Whenever the \l TapHandler's \c tapped signal is emitted, the \c send
343signal will automatically be emitted as well.