Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
focus.qdoc
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4/*!
5\page qtquick-input-focus.html
6\title Keyboard Focus in Qt Quick
7\brief handling keyboard focus
8
9When a key is pressed or released, a key event is generated and delivered to the
10focused Qt Quick \l Item. To facilitate the construction of reusable components
11and to address some of the cases unique to fluid user interfaces, the Qt Quick items add a
12scope based extension to Qt's traditional keyboard focus model.
13
14\tableofcontents
15
16\section1 Key Handling Overview
17
18When the user presses or releases a key, the following occurs:
19\list 1
20\li Qt receives the key action and generates a key event.
21\li If a \l QQuickWindow is the \l{QGuiApplication::focusWindow()}{focus window}
22of the application, the key event is delivered to it.
23\li The key event is delivered by the scene to the \l Item with
24\e {active focus}. If no item has active focus, the key event is ignored.
25\li If the \l QQuickItem with active focus accepts the key event, propagation
26stops. Otherwise the event is sent to the Item's parent until
27the event is accepted, or the root item is reached.
28
29If the \c {Rectangle} type in the following example has active focus and the \c A key is pressed,
30the event will not be propagated further. Upon pressing the \c B key, the event will propagate to the root
31item and thus be ignored.
32
33\snippet qml/focus/rectangle.qml simple key event
34\snippet qml/focus/rectangle.qml simple key event end
35
36\li If the root \l Item is reached, the key event is \l {QEvent::ignore()}{ignored} and regular Qt key handling continues.
37
38\endlist
39
40See also the \l {Keys}{Keys attached property} and \l {KeyNavigation}{KeyNavigation attached property}.
41
42\section1 Querying the Active Focus Item
43
44Whether or not an \l Item has active focus can be queried through the
45\c {Item::activeFocus} property. For example, here we have a \l Text
46type whose text is determined by whether or not it has active focus.
47
48\snippet qml/focus/rectangle.qml active focus
49
50\section1 Acquiring Focus and Focus Scopes
51
52An \l Item requests focus by setting the \c focus property to \c true.
53
54For very simple cases simply setting the \c focus property is sometimes
55sufficient. If we run the following example with the
56\l {Prototyping with the QML Runtime Tool}{qml tool},
57we see that the \c {keyHandler} type has active focus and
58pressing the \c A, \c B, or \c C keys modifies the text appropriately.
59
60\snippet qml/focus/basicwidget.qml focus true
61
62\image declarative-qmlfocus1.png
63
64However, were the above example to be used as a reusable or imported component,
65this simple use of the \c focus property is no longer sufficient.
66
67To demonstrate, we create two instances of our previously defined component and
68set the first one to have focus. The intention is that when the \c A, \c B, or
69\c C keys are pressed, the first of the two components receives the event and
70responds accordingly.
71
72The code that imports and creates two MyWidget instances:
73\snippet qml/focus/widget.qml window
74
75The MyWidget code:
76\snippet qml/focus/MyWidget.qml mywidget
77
78We want the first \c MyWidget object to have the focus, so we set its
79\c focus property to \c true. However, by running the code, we can confirm that
80the second widget receives the focus.
81
82\image declarative-qmlfocus2.png
83
84Looking at both \c MyWidget and \c window code, the problem is evident - there
85are three types that set the \c focus property to \c true. The two
86\c {MyWidget}s set the \c focus to \c true and the \c window component also sets the
87focus. Ultimately, only one type can have keyboard focus, and the system has
88to decide which type receives the focus. When the second \c MyWidget is created,
89it receives the focus because it is the last type to set its \c focus
90property to \c true.
91
92This problem is due to visibility. The \c MyWidget component would like to have
93the focus, but it cannot control the focus when it is imported or reused.
94Likewise, the \c window component does not have the ability to know if its
95imported components are requesting the focus.
96
97To solve this problem, QML introduces a concept known as a \e {focus scope}.
98For existing Qt users, a focus scope is like an automatic focus proxy.
99A focus scope is created by declaring the \l FocusScope type.
100
101In the next example, a \l FocusScope type is added to the component, and the
102visual result shown.
103
104\snippet qml/focus/myfocusscopewidget.qml widget in focusscope
105
106\image declarative-qmlfocus3.png
107
108
109Conceptually \e {focus scopes} are quite simple.
110\list
111\li Within each focus scope one object may have \c {Item::focus} set to
112\c true. If more than one \l Item has the \c focus property set, the
113last type to set the \c focus will have the focus and the others are unset,
114similar to when there are no focus scopes.
115\li When a focus scope receives active focus, the contained type with
116\c focus set (if any) also gets the active focus. If this type is
117also a \l FocusScope, the proxying behavior continues. Both the
118focus scope and the sub-focused item will have the \c activeFocus property set.
119\endlist
120
121Note that, since the FocusScope type is not a visual type, the properties
122of its children need to be exposed to the parent item of the FocusScope. Layouts
123and positioning types will use these visual and styling properties to create
124the layout. In our example, the \c Column type cannot display the two widgets
125properly because the FocusScope lacks visual properties of its own. The MyWidget
126component directly binds to the \c rectangle properties to allow the \c Column
127type to create the layout containing the children of the FocusScope.
128
129So far, the example has the second component statically selected. It is trivial
130now to extend this component to make it clickable, and add it to the original
131application. We still set one of the widgets as focused by default.
132Now, clicking either MyClickableWidget gives it focus and the other widget
133loses the focus.
134
135The code that imports and creates two MyClickableWidget instances:
136\snippet qml/focus/clickablewidget.qml clickable window
137
138The MyClickableWidget code:
139\snippet qml/focus/MyClickableWidget.qml clickable in focusscope
140
141\image declarative-qmlfocus4.png
142
143When a QML \l Item explicitly relinquishes focus (by setting its
144\c focus property to \c false while it has active focus), the
145system does not automatically select another type to receive focus. That is,
146it is possible for there to be no currently active focus.
147
148See \l{Qt Quick Examples - Key Interaction} for a
149demonstration of moving keyboard focus between multiple areas using FocusScope
150types.
151
152\section1 Advanced Uses of Focus Scopes
153
154Focus scopes allow focus to allocation to be easily partitioned. Several
155QML items use it to this effect.
156
157\l ListView, for example, is itself a focus scope. Generally this isn't
158noticeable as \l ListView doesn't usually have manually added visual children.
159By being a focus scope, \l ListView can focus the current list item without
160worrying about how that will effect the rest of the application. This allows the
161current item delegate to react to key presses.
162
163This contrived example shows how this works. Pressing the \c Return key will
164print the name of the current list item.
165
166\snippet qml/focus/advancedFocus.qml FocusScope delegate
167
168\image declarative-qmlfocus5.png
169
170While the example is simple, there is a lot going on behind the scenes. Whenever
171the current item changes, the \l ListView sets the delegate's \c {Item::focus}
172property. As the \l ListView is a focus scope, this doesn't affect the
173rest of the application. However, if the \l ListView itself has
174active focus this causes the delegate itself to receive active focus.
175In this example, the root type of the delegate is also a focus scope,
176which in turn gives active focus to the \l {TextInput} type that actually performs
177the work of handling the \c {Return} key.
178
179All of the QML view classes, such as \l PathView and \l GridView, behave
180in a similar manner to allow key handling in their respective delegates.
181*/