Qt Toolkit - Keyboard Focus Overview

| Classes - Annotated - Tree - Functions - Home - Structure

# Keyboard Focus Overview

Keyboard focus, like much else on the human end of a GUI, tends to be full of exceptions and not at all neat.

The basic problem is that the user's keystrokes can be directed at any of several windows on the screen, and any of several widgets inside the intended window. The user presses a key, wishing it to go to the right place. The window system is responsible for directing the keystroke to the window the user wishes, the application running that window for directing each keystroke to the widget the user wishes. Of course the user's wish moves at whim.

The application's responsibilities is the subject of this page.

## Focus motion

There are, historically, a few ways in which the user directs the keyboard focus at a desired widget:

1. The user presses Tab (or Shift-Tab) (or sometimes Enter).
2. The user clicks a widget.
3. The user presses a keyboard shortcut.
4. The user uses the mouse wheel.
5. The user moves the focus to this window, and the application has to guess to which widget.

Each of these motion mechanisms is different, and different types of widgets receive focus in only some of them. We'll cover each of them in turn.

## Tab/Shift-Tab.

Pressing Tab is by far the most common way to move focus using the keyboard. Sometimes in data-entry applications Enter does the same as Tab. We will ignore that for the moment.

Tab, in all window systems in common use today, moves the keyboard focus to the next widget in a circular per-window list. Tab moves focus along the circular list in one direction, Shift-Tab in the other. The order in which Tab moves is called the tab order.

In Qt, this list is kept in the QFocusData class. There is one QFocusData object per window, and widgets automatically append themselves to the end of it when QWidget::setFocusPolicy() is called with an appropriate QWidget::FocusPolicy. You can customize the tab order using QWidget::setTabOrder(). (If you don't, Tab generally moves focus in the order of widget construction.)

Since pressing Tab is so common, most widgets that can have focus should support tab focus. The major exception is widgets that are only seldom used, and where there is some keyboard accelerator or error handler that moves the focus.

For example, in a data entry dialog, there might be a field that is only necessary in one per cent of all cases. In such a dialog, Tab could skip this field, and the dialog could use one of these two mechanisms:

- If the program can determine whether the field is needed, it can move focus there when the user finishes entry and presses Ok, or when the user presses Enter after finishing the other fields.
- The label for the field can include a keyboard shortcut that moves focus to this field.

There is also another exception to Tab support is text-entry widgets that must support tab; almost all text editors fall into this class. Qt treats Control-Tab as Tab and Control-Shift-Tab as Shift-Tab, and such widgets can reimplement QWidget::event() and handle Tab before calling QWidget::event() to get normal processing of all other keys. However, since some systems use Control-Tab for other purposes, and many users aren't aware of Control-Tab anyway, this isn't a complete solution.

## The user clicks a widget.

This is perhaps even more common than pressing Tab on computers with a good mouse or other pointing device.

Clicking to move the focus is slightly more powerful than Tab. While it moves the focus to a widget, for editor widgets it also moves the text cursor (the widget's internal focus) to the spot where the mouse is clicked.

Since it is so common, it's a good idea to support it for most widgets. People are used to it. However, there is also an important reason to avoid it: You may not want to remove focus from the widget where it was.

For example, in a word processor, when the user clicks the 'B' (boldface) tool button, what should happen to the keyboard focus? Should it remain where it was, almost certainly in the editing widget, or should it move to the 'B' button?

We advise supporting click-to-focus for widgets that support text entry, and to avoid it for most widgets where a mouse click has a different effect. (For buttons, we also recommend adding a keyboard shortcut - QButton and its subclasses make that very easy.)

For widgets that don't fall into either class, we have no advice.

In Qt, only the QWidget::setFocusPolicy() function affects click-to-focus.

## The user presses a keyboard shortcut.

It's not unusual for keyboard shortcuts to move the focus. This can happen implicitly by opening modal dialogs, but also explicitly using focus accelerators such as are provided by QLabel::setBuddy(), QGroupBox and QTabBar.

We advise supporting shortcut focus for all widgets that the user may want to jump to. For example, a tab dialog can have keyboard shortcuts for each of its pages, so the user can press e.g. Alt-P to step to the Printing page. But don't overdo this - there are only a few keys, and it's also important to provide keyboard shortcuts for commands. Alt-P is also used for Paste, Play, Print and Print Here in the standard list of shortcuts, for example.

## The user uses the mouse wheel.

On Microsoft Windows, mouse wheel usage is always handled by the widget that has keyboard focus. On X11, it's handled by the widget that get other mouse events.

The way Qt handles this platform difference is by letting widgets move the keyboard focus when the wheel is used. With the right focus policy on each widget, applications can work idiomatically correctly on both Windows and X11.

## The user moves the focus to this window.

(and the application has to guess to which widget).

This can be simple: If the focus has been in this window before, then the last widget to have focus should regain it. Qt does that automatically.

If focus has never been in this window before and you know where focus should start out, call QWidget::setFocus() on that widget before you QWidget::show() it. If you don't, Qt will pick some suitable widget.