/**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:FDL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free ** Documentation License version 1.3 as published by the Free Software ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements ** will be met: http://www.gnu.org/copyleft/fdl.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ /*! \page qtquick-input-focus.html \title Keyboard Focus in Qt Quick \brief handling keyboard focus When a key is pressed or released, a key event is generated and delivered to the focused Qt Quick \l Item. To facilitate the construction of reusable components and to address some of the cases unique to fluid user interfaces, the Qt Quick items add a scope based extension to Qt's traditional keyboard focus model. \tableofcontents \section1 Key Handling Overview When the user presses or releases a key, the following occurs: \list 1 \li Qt receives the key action and generates a key event. \li If a \l QQuickWindow is the active window, the key event is delivered to it. \li The key event is delivered by the scene to the \l Item with \e {active focus}. If no item has active focus, the key event is ignored. \li If the \l QQuickItem with active focus accepts the key event, propagation stops. Otherwise the event is sent to the Item's parent until the event is accepted, or the root item is reached. If the \c {Rectangle} type in the following example has active focus and the \c A key is pressed, the event will not be propagated further. Upon pressing the \c B key, the event will propagate to the root item and thus be ignored. \snippet qml/focus/rectangle.qml simple key event \snippet qml/focus/rectangle.qml simple key event end \li If the root \l Item is reached, the key event is \l {QEvent::ignore()}{ignored} and regular Qt key handling continues. \endlist See also the \l {Keys}{Keys attached property} and \l {KeyNavigation}{KeyNavigation attached property}. \section1 Querying the Active Focus Item Whether or not an \l Item has active focus can be queried through the property \c {Item::activeFocus} property. For example, here we have a \l Text type whose text is determined by whether or not it has active focus. \snippet qml/focus/rectangle.qml active focus \section1 Acquiring Focus and Focus Scopes An \l Item requests focus by setting the \c focus property to \c true. For very simple cases simply setting the \c focus property is sometimes sufficient. If we run the following example with \l{qtquick-qmlscene.html} {qmlscene}, we see that the \c {keyHandler} type has active focus and pressing the \c A, \c B, or \c C keys modifies the text appropriately. \snippet qml/focus/basicwidget.qml focus true \image declarative-qmlfocus1.png However, were the above example to be used as a reusable or imported component, this simple use of the \c focus property is no longer sufficient. To demonstrate, we create two instances of our previously defined component and set the first one to have focus. The intention is that when the \c A, \c B, or \c C keys are pressed, the first of the two components receives the event and responds accordingly. The code that imports and creates two MyWidget instances: \snippet qml/focus/widget.qml window The MyWidget code: \snippet qml/focus/MyWidget.qml mywidget We would like to have the first MyWidget object to have the focus by setting its \c focus property to \c true. However, by running the code, we can confirm that the second widget receives the focus. \image declarative-qmlfocus2.png Looking at both \c MyWidget and \c window code, the problem is evident - there are three types that set the \c focus property set to \c true. The two MyWidget sets the \c focus to \c true and the \c window component also sets the focus. Ultimately, only one type can have keyboard focus, and the system has to decide which type receives the focus. When the second MyWidget is created, it receives the focus because it is the last type to set its \c focus property to \c true. This problem is due to visibility. The \c MyWidget component would like to have the focus, but it cannot control the focus when it is imported or reused. Likewise, the \c window component does not have the ability to know if its imported components are requesting the focus. To solve this problem, QML introduces a concept known as a \e {focus scope}. For existing Qt users, a focus scope is like an automatic focus proxy. A focus scope is created by declaring the \l FocusScope type. In the next example, a \l FocusScope type is added to the component, and the visual result shown. \snippet qml/focus/myfocusscopewidget.qml widget in focusscope \image declarative-qmlfocus3.png Conceptually \e {focus scopes} are quite simple. \list \li Within each focus scope one object may have \c {Item::focus} set to \c true. If more than one \l Item has the \c focus property set, the last type to set the \c focus will have the focus and the others are unset, similar to when there are no focus scopes. \li When a focus scope receives active focus, the contained type with \c focus set (if any) also gets the active focus. If this type is also a \l FocusScope, the proxying behavior continues. Both the focus scope and the sub-focused item will have the \c activeFocus property set. \endlist Note that, since the FocusScope type is not a visual type, the properties of its children need to be exposed to the parent item of the FocusScope. Layouts and positioning types will use these visual and styling properties to create the layout. In our example, the \c Column type cannot display the two widgets properly because the FocusScope lacks visual properties of its own. The MyWidget component directly binds to the \c rectangle properties to allow the \c Column type to create the layout containing the children of the FocusScope. So far, the example has the second component statically selected. It is trivial now to extend this component to make it clickable, and add it to the original application. We still set one of the widgets as focused by default. Now, clicking either MyClickableWidget gives it focus and the other widget loses the focus. The code that imports and creates two MyClickableWidget instances: \snippet qml/focus/clickablewidget.qml clickable window The MyClickableWidget code: \snippet qml/focus/MyClickableWidget.qml clickable in focusscope \image declarative-qmlfocus4.png When a QML \l Item explicitly relinquishes focus (by setting its \c focus property to \c false while it has active focus), the system does not automatically select another type to receive focus. That is, it is possible for there to be no currently active focus. See \l{Qt Quick Examples - Key Interaction} for a demonstration of moving keyboard focus between multiple areas using FocusScope types. \section1 Advanced Uses of Focus Scopes Focus scopes allow focus to allocation to be easily partitioned. Several QML items use it to this effect. \l ListView, for example, is itself a focus scope. Generally this isn't noticeable as \l ListView doesn't usually have manually added visual children. By being a focus scope, \l ListView can focus the current list item without worrying about how that will effect the rest of the application. This allows the current item delegate to react to key presses. This contrived example shows how this works. Pressing the \c Return key will print the name of the current list item. \snippet qml/focus/advancedFocus.qml FocusScope delegate \image declarative-qmlfocus5.png While the example is simple, there are a lot going on behind the scenes. Whenever the current item changes, the \l ListView sets the delegate's \c {Item::focus} property. As the \l ListView is a focus scope, this doesn't affect the rest of the application. However, if the \l ListView itself has active focus this causes the delegate itself to receive active focus. In this example, the root type of the delegate is also a focus scope, which in turn gives active focus to the \c {Text} type that actually performs the work of handling the \c {Return} key. All of the QML view classes, such as \l PathView and \l GridView, behave in a similar manner to allow key handling in their respective delegates. */