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