Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
signals.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2017 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4
/*!
5
\page qtqml-syntax-signals.html
6
7
\title Signal and Handler Event System
8
\brief the event system in QML
9
10
Application and user interface components need to communicate with each other. For
11
example, a button needs to know that the user has clicked on it.
12
The button may change colors to indicate its state or perform some logic. As
13
well, application needs to know whether the user is clicking the button. The
14
application may need to relay this clicking event to other applications.
15
16
QML has a signal and handler mechanism, where the \e signal is the event
17
and the signal is responded to through a \e {signal handler}. When a signal
18
is emitted, the corresponding signal handler is invoked. Placing logic such as
19
a script or other operations in the handler allows the component to respond to
20
the event.
21
22
\target qml-signals-and-handlers
23
\section1 Receiving signals with signal handlers
24
25
To receive a notification when a particular signal is emitted for a particular
26
object, 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
28
letter capitalized. The signal handler should contain the JavaScript code to be
29
executed when the signal handler is invoked.
30
31
For example, the \l [QtQuickControls]{Button} type from the
32
\l{Qt Quick Controls} module has a \c clicked signal, which
33
is emitted whenever the button is clicked. In this case, the signal handler for
34
receiving this signal should be \c onClicked. In the example below, whenever
35
the button is clicked, the \c onClicked handler is invoked, applying a random
36
color to the parent \l Rectangle:
37
38
\qml
39
import QtQuick
40
import QtQuick.Controls
41
42
Rectangle {
43
id: rect
44
width: 250; height: 250
45
46
Button {
47
anchors.bottom: parent.bottom
48
anchors.horizontalCenter: parent.horizontalCenter
49
text: "Change color!"
50
onClicked: {
51
rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
52
}
53
}
54
}
55
\endqml
56
57
\note Even though signal handlers look a bit like JavaScript functions, you
58
should not call them directly. If you need to share code between signal
59
handlers and other functionality, refactor it into a separate function.
60
Otherwise always emit the signal if you want the signal handler to be
61
called. There can be multiple handlers, in different scopes, for the
62
same signal.
63
64
\section2 Property change signal handlers
65
66
A signal is automatically emitted when the value of a QML property changes.
67
This type of signal is a \e {property change signal} and signal handlers for
68
these signals are written in the form \e on<Property>Changed, where
69
\e <Property> is the name of the property, with the first letter capitalized.
70
71
For example, the \l MouseArea type has a \l {MouseArea::pressed}{pressed} property.
72
To receive a notification whenever this property changes, write a signal handler
73
named \c onPressedChanged:
74
75
\qml
76
import QtQuick
77
78
Rectangle {
79
id: rect
80
width: 100; height: 100
81
82
TapHandler {
83
onPressedChanged: console.log("taphandler pressed?", pressed)
84
}
85
}
86
\endqml
87
88
Even though the \l TapHandler documentation does not document a signal handler
89
named \c onPressedChanged, the signal is implicitly provided by the fact that
90
the \c pressed property exists.
91
92
\section2 Signal parameters
93
94
Signals might have parameters. To access those, you should assign a function to the handler. Both
95
arrow functions and anonymous functions work.
96
97
For the following examples, consider a Status component with an errorOccurred signal (see
98
\l{Adding signals to custom QML types} for more information about how signals can be added to
99
QML components).
100
101
\qml
102
// Status.qml
103
import QtQuick
104
105
Item {
106
id: myitem
107
108
signal errorOccurred(message: string, line: int, column: int)
109
}
110
\endqml
111
112
\qml
113
Status {
114
onErrorOccurred: (mgs, line, col) => console.log(`${line}:${col}: ${msg}`)
115
}
116
\endqml
117
118
\note The names of the formal parameters in the function do not have to match those in the
119
signal.
120
121
If you do not need to handle all parameters, it is possible to omit trailing ones:
122
\qml
123
Status {
124
onErrorOccurred: message => console.log(message)
125
}
126
\endqml
127
128
It is not possible to leave out leading parameters you are interested in, however you can use some
129
placeholder name to indicate to readers that they are not important:
130
\qml
131
Status {
132
onErrorOccurred: (_, _, col) => console.log(`Error happened at column ${col}`)
133
}
134
\endqml
135
136
\note Instead of using a function, it is possible, but discouraged, to use a plain code block. In
137
that case all signal parameters get injected into the scope of the block. However, this can make
138
code difficult to read as it's unclear where the parameters come from, and results in slower
139
lookups in the QML engine. Injecting parameters in this way is deprecated, and will cause runtime
140
warnings if the parameter is actually used.
141
142
\section3 Using the arguments special object
143
144
In JavaScript you can refer to the \c arguments special
145
object, which, when available, allows to access the values of the
146
arguments passed to a non-arrow function as an array-like object.
147
148
It is usually available in the body of a function or code block that
149
is assigned to a signal handler.
150
151
When a code block or an anonymous function is assigned to the signal
152
handler, the special \c arguments object will provide the arguments
153
that were passed over by the signal.
154
155
For example, both of the following will print \c{[object Arguments] world undefined}:
156
157
\qml
158
import QtQml
159
160
QtObject {
161
id: root
162
163
signal hello(message: string)
164
165
onHello: { console.log(arguments, arguments[0], arguments[1]) }
166
167
Component.onCompleted: root.hello("world")
168
}
169
\endqml
170
171
\qml
172
import QtQml
173
174
QtObject {
175
id: root
176
177
signal hello(message: string)
178
179
onHello: function () { console.log(arguments, arguments[0], arguments[1]) }
180
181
Component.onCompleted: root.hello("world")
182
}
183
\endqml
184
185
The behavior will differ when an arrow function is assigned to the signal handler.
186
Then, it will still be possible to access the \c arguments
187
special object, but it will be an empty array-like object.
188
189
For example, the following will print \c{[object Arguments] undefined undefined}:
190
191
\qml
192
import QtQml
193
194
QtObject {
195
id: root
196
197
signal hello(message: string)
198
199
onHello: () => { console.log(arguments, arguments[0], arguments[1]) }
200
201
Component.onCompleted: root.hello("world")
202
}
203
\endqml
204
205
The difference in behavior is due to the way the \c{arguments} special
206
object interacts with arrow functions but is consistent with the general
207
behavior for bindings.
208
209
By specification, an arrow function does not carry its own
210
\c arguments special object.
211
As an arrow function still borrows from its enclosing context, it can
212
borrow the \c arguments special object if one is available.
213
214
A binding provides its own scope on evaluation.
215
In particular, the retrieval of the underlying arrow function is
216
performed in the scope provided by the evaluation of the binding.
217
218
In the scope of the binding no argument is provided, such that an
219
empty \c arguments special object will be available and borrowed by
220
the arrow function on retrieval.
221
222
As a non-arrow function does provide the \c arguments special object
223
in its own scope it can refer to the arguments that were provided to
224
the underlying function itself, which are the forwarded arguments
225
provided by the signal.
226
227
Usage of the \c arguments special object should generally be avoided
228
in favor of the usage of named parameters, which are more explicit and
229
work consistently indepedently of the usage of an arrow or a non-arrow
230
function.
231
232
\section2 Using the Connections type
233
234
In some cases it may be desirable to access a signal outside of the object that
235
emits it. For these purposes, the \c QtQuick module provides the \l Connections
236
type for connecting to signals of arbitrary objects. A \l Connections object
237
can receive any signal from its specified \l {Connections::target}{target}.
238
239
For example, the \c onClicked handler in the earlier example could have been
240
received by the root \l Rectangle instead, by placing the \c onClicked handler
241
in a \l Connections object that has its \l {Connections::target}{target} set to
242
the \c button:
243
244
\qml
245
import QtQuick
246
import QtQuick.Controls
247
248
Rectangle {
249
id: rect
250
width: 250; height: 250
251
252
Button {
253
id: button
254
anchors.bottom: parent.bottom
255
anchors.horizontalCenter: parent.horizontalCenter
256
text: "Change color!"
257
}
258
259
Connections {
260
target: button
261
function onClicked() {
262
rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
263
}
264
}
265
}
266
\endqml
267
268
269
\section2 Attached signal handlers
270
271
An \l {Attached Properties and Attached Signal Handlers}{attached signal handler}
272
receives a signal from an \e {attaching type} rather than the object within which
273
the handler is declared.
274
275
For example, \l{Component::completed}{Component.onCompleted} is an attached
276
signal handler. It is often used to execute some JavaScript code when its
277
creation process is complete. Here is an example:
278
279
\qml
280
import QtQuick
281
282
Rectangle {
283
width: 200; height: 200
284
color: Qt.rgba(Qt.random(), Qt.random(), Qt.random(), 1)
285
286
Component.onCompleted: {
287
console.log("The rectangle's color is", color)
288
}
289
}
290
\endqml
291
292
The \c onCompleted handler is not responding to a \c completed signal from
293
the \l Rectangle type. Instead, an object of the \c Component \e{attaching type}
294
with a \c completed signal has automatically been \e attached to the \l Rectangle
295
object by the QML engine. The engine emits this signal when the Rectangle object is
296
created, thus triggering the \c Component.onCompleted signal handler.
297
298
Attached signal handlers allow objects to be notified of particular signals that are
299
significant to each individual object. If there was no \c Component.onCompleted
300
attached signal handler, for example, an object could not receive this notification
301
without registering for some special signal from some special object.
302
The \e {attached signal handler} mechanism enables objects to receive particular
303
signals without extra code.
304
305
See \l {Attached properties and attached signal handlers} for more information on
306
attached signal handlers.
307
308
\section1 Adding signals to custom QML types
309
310
Signals can be added to custom QML types through the \c signal keyword.
311
312
The syntax for defining a new signal is:
313
314
\tt{signal <name>[([<type> <parameter name>[, ...]])]}
315
316
A signal is emitted by invoking the signal as a method.
317
318
For example, the code below is defined in a file named \c SquareButton.qml. The
319
root \l Rectangle object has an \c activated signal, which is emitted whenever the
320
child \l TapHandler is \c tapped. In this particular example the activated signal
321
is emitted with the x and y coordinates of the mouse click:
322
323
\qml
324
// SquareButton.qml
325
import QtQuick
326
327
Rectangle {
328
id: root
329
330
signal activated(real xPosition, real yPosition)
331
property point mouseXY
332
property int side: 100
333
width: side; height: side
334
335
TapHandler {
336
id: handler
337
onTapped: root.activated(root.mouseXY.x, root.mouseXY.y)
338
onPressedChanged: root.mouseXY = handler.point.position
339
}
340
}
341
\endqml
342
343
Now any objects of the \c SquareButton can connect to the \c activated signal using an \c onActivated signal handler:
344
345
\qml
346
// myapplication.qml
347
SquareButton {
348
onActivated: (xPosition, yPosition) => console.log(`Activated at {xPosition}, ${yPosition}`)
349
}
350
\endqml
351
352
See \l {Signal Attributes} for more details on writing signals for custom QML types.
353
354
355
\target qml-connect-signals-to-method
356
\section1 Connecting signals to methods and signals
357
358
Signal objects have a \c connect() method to a connect a signal either to a
359
method or another signal. When a signal is connected to a method, the method is
360
automatically invoked whenever the signal is emitted. This mechanism enables a
361
signal to be received by a method instead of a signal handler.
362
363
Below, the \c messageReceived signal is connected to three methods using the \c connect() method:
364
365
\qml
366
import QtQuick
367
368
Rectangle {
369
id: relay
370
371
signal messageReceived(string person, string notice)
372
373
Component.onCompleted: {
374
relay.messageReceived.connect(sendToPost)
375
relay.messageReceived.connect(sendToTelegraph)
376
relay.messageReceived.connect(sendToEmail)
377
relay.messageReceived("Tom", "Happy Birthday")
378
}
379
380
function sendToPost(person: string, notice: string) {
381
console.log(`Sending to post: ${person}, ${notice}`)
382
}
383
function sendToTelegraph(person: string, notice: string) {
384
console.log(`Sending to telegraph: ${person}, ${notice}`)
385
}
386
function sendToEmail(person: string, notice: string) {
387
console.log(`Sending to email: ${person}, ${notice}`)
388
}
389
}
390
\endqml
391
392
In many cases it is sufficient to receive signals through signal handlers
393
rather than using the connect() function. However, using the \c connect
394
method allows a signal to be received by multiple methods as shown earlier,
395
which would not be possible with signal handlers as they must be uniquely
396
named. Also, the \c connect method is useful when connecting signals to
397
\l {Dynamic QML Object Creation from JavaScript}{dynamically created objects}.
398
399
There is a corresponding \c disconnect() method for removing connected signals:
400
401
\qml
402
Rectangle {
403
id: relay
404
//...
405
406
function removeTelegraphSignal() {
407
relay.messageReceived.disconnect(sendToTelegraph)
408
}
409
}
410
\endqml
411
412
\section3 Signal to signal connect
413
414
By connecting signals to other signals, the \c connect() method can form different
415
signal chains.
416
417
\qml
418
import QtQuick
419
420
Rectangle {
421
id: forwarder
422
width: 100; height: 100
423
424
signal send()
425
onSend: console.log("Send clicked")
426
427
TapHandler {
428
id: mousearea
429
anchors.fill: parent
430
onTapped: console.log("Mouse clicked")
431
}
432
433
Component.onCompleted: {
434
mousearea.tapped.connect(send)
435
}
436
}
437
\endqml
438
439
440
Whenever the \l TapHandler's \c tapped signal is emitted, the \c send
441
signal will automatically be emitted as well.
442
443
\code
444
output:
445
MouseArea clicked
446
Send clicked
447
\endcode
448
449
\note Connections to function objects will stay alive as long as the sender of the signal is alive.
450
This behavior is analogous to the 3-argument version of QObject::connect() in C++.
451
452
\qml
453
Window {
454
visible: true
455
width: 400
456
height: 400
457
458
Item {
459
id: item
460
property color globalColor: "red"
461
462
Button {
463
text: "Change global color"
464
onPressed: {
465
item.globalColor = item.globalColor === Qt.color("red") ? "green" : "red"
466
}
467
}
468
469
Button {
470
x: 150
471
text: "Clear rectangles"
472
onPressed: repeater.model = 0
473
}
474
475
Repeater {
476
id: repeater
477
model: 5
478
Rectangle {
479
id: rect
480
color: "red"
481
width: 50
482
height: 50
483
x: (width + 2) * index + 2
484
y: 100
485
Component.onCompleted: {
486
if (index % 2 === 0) {
487
item.globalColorChanged.connect(() => {
488
color = item.globalColor
489
})
490
}
491
}
492
}
493
}
494
}
495
}
496
\endqml
497
498
In the contrived example above, the goal is to flip the color of every even rectangle to follow
499
some global color. To achieve this, for every even rectangle, a connection is made between the
500
globalColorChanged signal and a function to set the rectangle's color. This works as expected while
501
the rectangles are alive. However, once the clear button is pressed, the rectangles are gone but
502
the function handling the signal is still called every time the signal is emitted. This can be
503
seen by the error messages thrown by the function trying to run in the background when changing
504
the global color.
505
506
In the current setup, the connections would only be destroyed once the item holding
507
globalColor is destroyed. To prevent the connections from lingering on, they can be explicitly
508
disconnected when the rectangles are being destroyed.
509
*/
qtdeclarative
src
qml
doc
src
qmllanguageref
syntax
signals.qdoc
Generated on
for Qt by
1.14.0