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
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\section1 Key Handling Overview
15
16When the user presses or releases a key, the following occurs:
17\list 1
18\li Qt receives the key action and generates a key event.
19\li If a \l QQuickWindow is the \l{QGuiApplication::focusWindow()}{focus window}
20of the application, the key event is delivered to it.
21\li The key event is delivered by the scene to the \l Item with
22\e {active focus}. If no item has active focus, the key event is ignored.
23\li If the \l QQuickItem with active focus accepts the key event, propagation
24stops. Otherwise the event is sent to the Item's parent until
25the event is accepted, or the root item is reached.
26
27If the \c {Rectangle} type in the following example has active focus and the \c A key is pressed,
28the event will not be propagated further. Upon pressing the \c B key, the event will propagate to the root
29item and thus be ignored.
30
31\snippet qml/focus/rectangle.qml simple key event
32\snippet qml/focus/rectangle.qml simple key event end
33
34\li If the root \l Item is reached, the key event is \l {QEvent::ignore()}{ignored} and regular Qt key handling continues.
35
36\endlist
37
38See also the \l {Keys}{Keys attached property} and \l {KeyNavigation}{KeyNavigation attached property}.
39
40\section1 Querying the Active Focus Item
41
42Whether or not an \l Item has active focus can be queried through the
43\c {Item::activeFocus} property. For example, here we have a \l Text
44type whose text is determined by whether or not it has active focus.
45
46\snippet qml/focus/rectangle.qml active focus
47
48\section1 Acquiring Focus and Focus Scopes
49
50An \l Item requests focus by setting the \c focus property to \c true.
51
52For very simple cases simply setting the \c focus property is sometimes
53sufficient. If we run the following example with the
54\l {Prototyping with the QML Runtime Tool}{qml tool},
55we see that the \c {keyHandler} type has active focus and
56pressing the \c A, \c B, or \c C keys modifies the text appropriately.
57
58\snippet qml/focus/basicwidget.qml focus true
59
60\image declarative-qmlfocus1.png {Blue rounded widget showing Key C was pressed}
61
62However, were the above example to be used as a reusable or imported component,
63this simple use of the \c focus property is no longer sufficient.
64
65To demonstrate, we create two instances of our previously defined component and
66set the first one to have focus. The intention is that when the \c A, \c B, or
67\c C keys are pressed, the first of the two components receives the event and
68responds accordingly.
69
70The code that imports and creates two MyWidget instances:
71\snippet qml/focus/widget.qml window
72
73The MyWidget code:
74\snippet qml/focus/MyWidget.qml mywidget
75
76We want the first \c MyWidget object to have the focus, so we set its
77\c focus property to \c true. However, by running the code, it can happen that
78the second widget receives the focus.
79
80\image declarative-qmlfocus2.png
81 {Two stacked widgets with second green one showing Key A was pressed}
82
83Looking at both \c MyWidget and \c window code, the problem is evident - there
84are three types that set the \c focus property to \c true. The two
85\c {MyWidget}s set the \c focus to \c true and the \c window component also sets the
86focus. Ultimately, only one type can have keyboard focus, and the system has
87to decide which type receives the focus. Since QML does not guarantee which element
88will have its properties initialized first, it might be that the last \c MyWidget
89gets the initial focus.
90
91This problem is due to visibility. The \c MyWidget component would like to have
92the focus, but it cannot control the focus when it is imported or reused.
93Likewise, the \c window component does not have the ability to know if its
94imported components are requesting the focus.
95
96To solve this problem, QML introduces a concept known as a \e {focus scope}.
97For existing Qt users, a focus scope is like an automatic focus proxy.
98A focus scope is created by declaring the \l FocusScope type.
99
100In the next example, a \l FocusScope type is added to the component, and the
101visual result shown.
102
103\snippet qml/focus/myfocusscopewidget.qml widget in focusscope
104
105\image declarative-qmlfocus3.png
106 {Two stacked widgets with first blue one showing Key B was pressed}
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 {Two clickable widgets each displaying their last pressed key}
143
144When a QML \l Item explicitly relinquishes focus (by setting its
145\c focus property to \c false while it has active focus), the
146system does not automatically select another type to receive focus. That is,
147it is possible for there to be no currently active focus.
148
149See \l{Qt Quick Examples - Key Interaction} for a
150demonstration of moving keyboard focus between multiple areas using FocusScope
151types.
152
153\section1 Advanced Uses of Focus Scopes
154
155Focus scopes allow focus to allocation to be easily partitioned. Several
156QML items use it to this effect.
157
158\l ListView, for example, is itself a focus scope. Generally this isn't
159noticeable as \l ListView doesn't usually have manually added visual children.
160By being a focus scope, \l ListView can focus the current list item without
161worrying about how that will effect the rest of the application. This allows the
162current item delegate to react to key presses.
163
164This contrived example shows how this works. Pressing the \c Return key will
165print the name of the current list item.
166
167\snippet qml/focus/advancedFocus.qml FocusScope delegate
168
169\image declarative-qmlfocus5.png {List with three editable names: Bob, John, Michael}
170
171While the example is simple, there is a lot going on behind the scenes. Whenever
172the current item changes, the \l ListView sets the delegate's \c {Item::focus}
173property. As the \l ListView is a focus scope, this doesn't affect the
174rest of the application. However, if the \l ListView itself has
175active focus this causes the delegate itself to receive active focus.
176In this example, the root type of the delegate is also a focus scope,
177which in turn gives active focus to the \l {TextInput} type that actually performs
178the work of handling the \c {Return} key.
179
180All of the QML view classes, such as \l PathView and \l GridView, behave
181in a similar manner to allow key handling in their respective delegates.
182*/