| 1 | /**************************************************************************** | 
|---|
| 2 | ** | 
|---|
| 3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | 
|---|
| 4 | ** All rights reserved. | 
|---|
| 5 | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
|---|
| 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 qt-info@nokia.com. | 
|---|
| 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 | */ | 
|---|