-
Notifications
You must be signed in to change notification settings - Fork 0
2.02
Explanation of the contents of a topic page @ Topic reference page
Objective: Controlling focus and handling key presses
- What is keyboard focus?
- What is mouse grab?
- What is keyboard grab?
- What is an attached property (Keys, for example)?
- How do you grab specific key presses?
- How do you grab generic key presses?
- How do you get focus?
- How do you change focus?
- What is FocusScope?
- How do you forward a key press to a parent?
http://doc.qt.io/qt-5/qml-qtquick-keys.html#details
http://doc.qt.io/qt-5/qtquick-input-focus.html
http://doc.qt.io/qt-5/qml-qtquick-keyevent.html
http://doc.qt.io/qt-5/qml-qtquick-keynavigation.html
- Navigation between items (Changing the focused item, directional(arrow keys), tab and backtab)
Qt has two types that display text input - TextEdit and TextInput. TextEdit displays multiple lines of input, where as TextInput displays a single line of text input.
TextInput
The TextInput type displays a single line of editable plain text.
TextInput is used to accept a line of text input. Input constraints can be placed on a TextInput item (for example, through a validator or inputMask), and setting echoMode to an appropriate value enables TextInput to be used for a password input field.
TextEdit
The TextEdit item displays a block of editable, formatted text.
It can display both plain and rich text. For example:
TextEdit {
width: 240
text: "<b>Hello</b> <i>World!</i>"
font.family: "Helvetica"
font.pointSize: 20
color: "blue"
focus: true
}Setting focus to true enables the TextEdit item to receive keyboard focus.
Note that the TextEdit does not implement scrolling, following the cursor, or other behaviors specific to a look-and-feel. For example, to add flickable scrolling that follows the cursor:
Flickable {
id: flick
width: 300
height: 200
contentWidth: edit.paintedWidth
contentHeight: edit.paintedHeight
clip: true
function ensureVisible(r) {
if (contentX >= r.x)
contentX = r.x
else if (contentX + width <= r.x + r.width)
contentX = r.x + r.width - width
if (contentY >= r.y)
contentY = r.y
else if (contentY + height <= r.y + r.height)
contentY = r.y + r.height - height
}
TextEdit {
id: edit
width: flick.width
focus: true
wrapMode: TextEdit.Wrap
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
}
}A particular look-and-feel might use smooth scrolling (eg. using SmoothedAnimation), might have a visible scrollbar, or a scrollbar that fades in to show location, etc.
Clipboard support is provided by the cut(), copy(), and paste() functions, and the selection can be handled in a traditional "mouse" mechanism by setting selectByMouse, or handled completely from QML by manipulating selectionStart and selectionEnd, or using selectAll() or selectWord().
You can translate between cursor positions (characters from the start of the document) and pixel points using positionAt() and positionToRectangle().
The Keys QML type is responsible for key handling. Keys can be handled via the onPressed and onReleased signal properties.
The signal properties have a KeyEvent parameter, named event which contains details of the event. If a key is handled event.accepted should be set to true to prevent the event from propagating up the item hierarchy.
The following example shows how the general onPressed handler can be used to test for a certain key; in this case, the left cursor key:
Item {
anchors.fill: parent
focus: true
Keys.onPressed: {
if (event.key === Qt.Key_Left) {
console.log("move left")
event.accepted = true
}
}
}Some keys may alternatively be handled via specific signal properties, for example onSelectPressed. These handlers automatically set event.accepted to true.
Item {
anchors.fill: parent
focus: true
Keys.onLeftPressed: console.log("move left")
}The Keys attached property can be configured to handle key events before or after the item it is attached to. This makes it possible to intercept events in order to override an item's default behavior, or act as a fallback for keys not handled by the item.
If priority is Keys.BeforeItem (default) the order of key event processing is:
- Items specified in forwardTo
- specific key handlers, e.g. onReturnPressed
- onPressed, onReleased handlers
- Item specific key handling, e.g. TextInput key handling
- parent item
If priority is Keys.AfterItem the order of key event processing is:
- Item specific key handling, e.g. TextInput key handling 2.Items specified in forwardTo
- specific key handlers, e.g. onReturnPressed
- onPressed, onReleased handlers
- parent item
If the event is accepted during any of the above steps, key propagation stops.
In UIs with just one TextInput focus is assigned automatically. In UIs with more than one TextInput focus needs to be changed via clicking.
What happens if a TextInput has no text?
In that case there is no way to click on it, unless it has a width or uses anchors.
Focus is assigned trough setting the focus property.
TextInput {
id: upperTextInput
anchors.left: parent.left
anchors.right: parent.right
text: "Field 1"
font.pixelSize: 32
color: focus ? "black" : "gray"
}
TextInput {
anchors.left: parent.left
anchors.top: upperTextInput.bottom
anchors.right: parent.right
text: qsTr("Field 2")
font.pixelSize: 32
color: focus ? "black" : "gray"
}The nameField item defines KeyNavigation.tab, which results to pressing Tab moving the focus to the addressField item
TextInput {
id: nameField
focus: true
KeyNavigation.tab: addressField
}The addressField item defines KeyNavigation.backtab, which results to pressing Shift+Tab moving focus to the nameField item.
TextInput {
id: addressField
KeyNavigation.backtab: nameField
}http://doc.qt.io/qt-5/qml-qtquick-focusscope.html#details
Focus scopes assist in keyboard focus handling when building reusable QML components.
A focus scope declares that the last child element with focus:true receives the focus if the focus scope receives the focus. So it’s forward the focus to the last focus requesting child element. We will create a 2nd version of our TLineEdit component called TLineEditV2 using the focus scope as root element.
When a key is pressed or released, a key event is generated and delivered to the focused Qt Quick 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.
Key Handling Overview
When the user presses or releases a key, the following occurs:
- Qt receives the key action and generates a key event.
- If a QQuickWindow is the active window, the key event is delivered to it.
- The key event is delivered by the scene to the Item with active focus. If no item has active focus, the key event is ignored.
- If the 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 Rectangle type in the following example has active focus and the A key is pressed, the event will not be propagated further. Upon pressing the B key, the event will propagate to the root item and thus be ignored.
Rectangle {
width: 100
height: 100
focus: true
Keys.onPressed: {
if (event.key == Qt.Key_A) {
console.log('Key A was pressed')
event.accepted = true
}
}
}