1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation ([email protected])
|
---|
6 | **
|
---|
7 | ** This file is part of the documentation of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:FDL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in a
|
---|
14 | ** written agreement between you and Nokia.
|
---|
15 | **
|
---|
16 | ** GNU Free Documentation License
|
---|
17 | ** Alternatively, this file may be used under the terms of the GNU Free
|
---|
18 | ** Documentation License version 1.3 as published by the Free Software
|
---|
19 | ** Foundation and appearing in the file included in the packaging of this
|
---|
20 | ** file.
|
---|
21 | **
|
---|
22 | ** If you have questions regarding the use of this file, please contact
|
---|
23 | ** Nokia at [email protected].
|
---|
24 | ** $QT_END_LICENSE$
|
---|
25 | **
|
---|
26 | ****************************************************************************/
|
---|
27 |
|
---|
28 | /*!
|
---|
29 | \target qmlfocus
|
---|
30 | \page qdeclarativefocus.html
|
---|
31 | \title Keyboard Focus in QML
|
---|
32 |
|
---|
33 | When a key is pressed or released, a key event is generated and delivered to the
|
---|
34 | focused QML \l Item. To facilitate the construction of reusable components
|
---|
35 | and to address some of the cases unique to fluid user interfaces, the QML items add a
|
---|
36 | \e scope based extension to Qt's traditional keyboard focus model.
|
---|
37 |
|
---|
38 | \tableofcontents
|
---|
39 |
|
---|
40 | \section1 Key Handling Overview
|
---|
41 |
|
---|
42 | When the user presses or releases a key, the following occurs:
|
---|
43 | \list 1
|
---|
44 | \o Qt receives the key action and generates a key event.
|
---|
45 | \o If the Qt widget containing the \l QDeclarativeView has focus, the key event
|
---|
46 | is delivered to it. Otherwise, regular Qt key handling continues.
|
---|
47 | \o The key event is delivered by the scene to the QML \l Item with
|
---|
48 | \e {active focus}. If no Item has active focus, the key event is
|
---|
49 | \l {QEvent::ignore()}{ignored} and regular Qt key handling continues.
|
---|
50 | \o If the QML Item with active focus accepts the key event, propagation
|
---|
51 | stops. Otherwise the event is "bubbled up", by recursively passing it to each
|
---|
52 | Item's parent until either the event is accepted, or the root Item is reached.
|
---|
53 |
|
---|
54 | If the \c {Rectangle} element in the following example has active focus and the \c A key is pressed,
|
---|
55 | it will bubble up to its parent. However, pressing the \c B key will bubble up to the root
|
---|
56 | item and thus subsequently be ignored.
|
---|
57 |
|
---|
58 | \snippet doc/src/snippets/declarative/focus/rectangle.qml simple key event
|
---|
59 | \snippet doc/src/snippets/declarative/focus/rectangle.qml simple key event end
|
---|
60 |
|
---|
61 | \o If the root \l Item is reached, the key event is \l {QEvent::ignore()}{ignored} and regular Qt key handling continues.
|
---|
62 |
|
---|
63 | \endlist
|
---|
64 |
|
---|
65 | See also the \l {Keys}{Keys attached property} and \l {KeyNavigation}{KeyNavigation attached property}.
|
---|
66 |
|
---|
67 | \section1 Querying the Active Focus Item
|
---|
68 |
|
---|
69 | Whether or not an \l Item has active focus can be queried through the
|
---|
70 | property \c {Item::activeFocus} property. For example, here we have a \l Text
|
---|
71 | element whose text is determined by whether or not it has active focus.
|
---|
72 |
|
---|
73 | \snippet doc/src/snippets/declarative/focus/rectangle.qml active focus
|
---|
74 |
|
---|
75 | \section1 Acquiring Focus and Focus Scopes
|
---|
76 |
|
---|
77 | An \l Item requests focus by setting the \c focus property to \c true.
|
---|
78 |
|
---|
79 | For very simple cases simply setting the \c focus property is sometimes
|
---|
80 | sufficient. If we run the following example with the \l {QML Viewer}, we see that
|
---|
81 | the \c {keyHandler} element has active focus and pressing the \c A, \c B,
|
---|
82 | or \c C keys modifies the text appropriately.
|
---|
83 |
|
---|
84 | \snippet doc/src/snippets/declarative/focus/basicwidget.qml focus true
|
---|
85 |
|
---|
86 | \image declarative-qmlfocus1.png
|
---|
87 |
|
---|
88 | However, were the above example to be used as a reusable or imported component,
|
---|
89 | this simple use of the \c focus property is no longer sufficient.
|
---|
90 |
|
---|
91 | To demonstrate, we create two instances of our previously defined component and
|
---|
92 | set the first one to have focus. The intention is that when the \c A, \c B, or
|
---|
93 | \c C keys are pressed, the first of the two components receives the event and
|
---|
94 | responds accordingly.
|
---|
95 |
|
---|
96 | The code that imports and creates two MyWidget instances:
|
---|
97 | \snippet doc/src/snippets/declarative/focus/widget.qml window
|
---|
98 |
|
---|
99 | The MyWidget code:
|
---|
100 | \snippet doc/src/snippets/declarative/focus/mywidget.qml mywidget
|
---|
101 |
|
---|
102 | We would like to have the first MyWidget object to have the focus by setting its
|
---|
103 | \c focus property to \c true. However, by running the code, we can confirm that
|
---|
104 | the second widget receives the focus.
|
---|
105 |
|
---|
106 | \image declarative-qmlfocus2.png
|
---|
107 |
|
---|
108 | Looking at both \c MyWidget and \c window code, the problem is evident - there
|
---|
109 | are three elements that set the \c focus property set to \c true. The two
|
---|
110 | MyWidget sets the \c focus to \c true and the \c window component also sets the
|
---|
111 | focus. Ultimately, only one element can have keyboard focus, and the system has
|
---|
112 | to decide which element receives the focus. When the second MyWidget is created,
|
---|
113 | it receives the focus because it is the last element to set its \c focus
|
---|
114 | property to \c true.
|
---|
115 |
|
---|
116 | This problem is due to visibility. The \c MyWidget component would like to have
|
---|
117 | the focus, but it cannot control the focus when it is imported or reused.
|
---|
118 | Likewise, the \c window component does not have the ability to know if its
|
---|
119 | imported components are requesting the focus.
|
---|
120 |
|
---|
121 | To solve this problem, the QML introduces a concept known as a \e {focus scope}.
|
---|
122 | For existing Qt users, a focus scope is like an automatic focus proxy.
|
---|
123 | A focus scope is created by declaring the \l FocusScope element.
|
---|
124 |
|
---|
125 | In the next example, a \l FocusScope element is added to the component, and the
|
---|
126 | visual result shown.
|
---|
127 |
|
---|
128 | \snippet doc/src/snippets/declarative/focus/myfocusscopewidget.qml widget in focusscope
|
---|
129 |
|
---|
130 | \image declarative-qmlfocus3.png
|
---|
131 |
|
---|
132 |
|
---|
133 | Conceptually \e {focus scopes} are quite simple.
|
---|
134 | \list
|
---|
135 | \o Within each focus scope one element may have \c {Item::focus} set to
|
---|
136 | \c true. If more than one \l Item has the \c focus property set, the
|
---|
137 | last element to set the \c focus will have the focus and the others are unset,
|
---|
138 | similar to when there are no focus scopes.
|
---|
139 | \o When a focus scope receives active focus, the contained element with
|
---|
140 | \c focus set (if any) also gets the active focus. If this element is
|
---|
141 | also a \l FocusScope, the proxying behavior continues. Both the
|
---|
142 | focus scope and the sub-focused item will have \c activeFocus property set.
|
---|
143 | \endlist
|
---|
144 |
|
---|
145 | Note that, since the FocusScope element is not a visual element, the properties
|
---|
146 | of its children need to be exposed to the parent item of the FocusScope. Layouts
|
---|
147 | and positioning elements will use these visual and styling properties to create
|
---|
148 | the layout. In our example, the \c Column element cannot display the two widgets
|
---|
149 | properly because the FocusScope lacks visual properties of its own. The MyWidget
|
---|
150 | component directly binds to the \c rectangle properties to allow the \c Column
|
---|
151 | element to create the layout containing the children of the FocusScope.
|
---|
152 |
|
---|
153 | So far, the example has the second component statically selected. It is trivial
|
---|
154 | now to extend this component to make it clickable, and add it to the original
|
---|
155 | application. We still set one of the widgets as focused by default.
|
---|
156 | Now, clicking either MyClickableWidget gives it focus and the other widget
|
---|
157 | loses the focus.
|
---|
158 |
|
---|
159 | The code that imports and creates two MyClickableWidget instances:
|
---|
160 | \snippet doc/src/snippets/declarative/focus/clickablewidget.qml clickable window
|
---|
161 |
|
---|
162 | The MyClickableWidget code:
|
---|
163 | \snippet doc/src/snippets/declarative/focus/myclickablewidget.qml clickable in focusscope
|
---|
164 |
|
---|
165 | \image declarative-qmlfocus4.png
|
---|
166 |
|
---|
167 | When a QML \l Item explicitly relinquishes focus (by setting its
|
---|
168 | \c focus property to \c false while it has active focus), the
|
---|
169 | system does not automatically select another element to receive focus. That is,
|
---|
170 | it is possible for there to be no currently active focus.
|
---|
171 |
|
---|
172 | See the \l{declarative/keyinteraction/focus}{Keyboard Focus example} for a
|
---|
173 | demonstration of moving keyboard focus between multiple areas using FocusScope
|
---|
174 | elements.
|
---|
175 |
|
---|
176 | \section1 Advanced uses of Focus Scopes
|
---|
177 |
|
---|
178 | Focus scopes allow focus to allocation to be easily partitioned. Several
|
---|
179 | QML items use it to this effect.
|
---|
180 |
|
---|
181 | \l ListView, for example, is itself a focus scope. Generally this isn't
|
---|
182 | noticeable as \l ListView doesn't usually have manually added visual children.
|
---|
183 | By being a focus scope, \l ListView can focus the current list item without
|
---|
184 | worrying about how that will effect the rest of the application. This allows the
|
---|
185 | current item delegate to react to key presses.
|
---|
186 |
|
---|
187 | This contrived example shows how this works. Pressing the \c Return key will
|
---|
188 | print the name of the current list item.
|
---|
189 |
|
---|
190 | \snippet doc/src/snippets/declarative/focus/advancedFocus.qml FocusScope delegate
|
---|
191 |
|
---|
192 | \image declarative-qmlfocus5.png
|
---|
193 |
|
---|
194 | While the example is simple, there are a lot going on behind the scenes. Whenever
|
---|
195 | the current item changes, the \l ListView sets the delegate's \c {Item::focus}
|
---|
196 | property. As the \l ListView is a focus scope, this doesn't affect the
|
---|
197 | rest of the application. However, if the \l ListView itself has
|
---|
198 | active focus this causes the delegate itself to receive active focus.
|
---|
199 | In this example, the root element of the delegate is also a focus scope,
|
---|
200 | which in turn gives active focus to the \c {Text} element that actually performs
|
---|
201 | the work of handling the \c {Return} key.
|
---|
202 |
|
---|
203 | All of the QML view classes, such as \l PathView and \l GridView, behave
|
---|
204 | in a similar manner to allow key handling in their respective delegates.
|
---|
205 | */
|
---|