225 lines
8.9 KiB
Plaintext
225 lines
8.9 KiB
Plaintext
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
|
** All rights reserved.
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
**
|
|
** This file is part of the documentation of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:FDL$
|
|
** GNU Free Documentation License
|
|
** 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.
|
|
**
|
|
** Other Usage
|
|
** Alternatively, this file may be used in accordance with the terms
|
|
** and conditions contained in a signed written agreement between you
|
|
** and Nokia.
|
|
**
|
|
**
|
|
**
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
/*!
|
|
\example tools/inputpanel
|
|
\title Input Panel Example
|
|
|
|
The Input Panel example shows how to create an input panel that
|
|
can be used to input text into widgets using only the pointer and
|
|
no keyboard.
|
|
|
|
\image inputpanel-example.png
|
|
|
|
The input fields in the main window have no function other than
|
|
to accept input. The main focus is on how the extra input panel
|
|
can be used to input text without the need for a real keyboard or
|
|
keypad.
|
|
|
|
\section1 Main Form Class Definition
|
|
|
|
Because the main window has no other function than to accept
|
|
input, it has no class definition. Instead, its whole layout is
|
|
made in Qt Designer. This emphasizes the point that no widget
|
|
specific code is needed to use input panels with Qt.
|
|
|
|
\section1 MyInputPanelContext Class Definition
|
|
|
|
\snippet examples/tools/inputpanel/myinputpanelcontext.h 0
|
|
|
|
The \c MyInputPanelContext class inherits QInputContext, which is
|
|
Qt's base class for handling input methods.
|
|
\c MyInputPanelContext is responsible for managing the state of
|
|
the input panel and sending input method events to the receiving
|
|
widgets.
|
|
|
|
The \c inputPanel member is a pointer to the input panel widget
|
|
itself; in other words, the window that will display the buttons
|
|
used for input.
|
|
|
|
The \c identifierName(), \c language(), \c isComposing() and
|
|
\c reset() functions are there mainly to fill in the pure virtual
|
|
functions in the base class, QInputContext, but they can be
|
|
useful in other scenarios. The important functions and slots are
|
|
the following:
|
|
|
|
\list
|
|
\o \c filterEvent() is where we receive events telling us to open
|
|
or close the input panel.
|
|
\o \c sendCharacter() is a slot which is called when we want to
|
|
send a character to the focused widget.
|
|
\o \c updatePosition() is used to position the input panel
|
|
relative to the focused widget, and will be used when opening
|
|
the input panel.
|
|
\endlist
|
|
|
|
\section1 MyInputPanelContext Class Implementation
|
|
|
|
In the constructor we connect to the \c characterGenerated()
|
|
signal of the input panel, in order to receive key presses. We'll
|
|
see how it works in detail later on.
|
|
|
|
\snippet examples/tools/inputpanel/myinputpanelcontext.cpp 0
|
|
|
|
In the \c filterEvent() function, we must look for the two event
|
|
types: \c RequestSoftwareInputPanel and \c CloseSoftwareInputPanel.
|
|
|
|
\snippet examples/tools/inputpanel/myinputpanelcontext.cpp 1
|
|
|
|
The first type will be sent whenever
|
|
an input capable widget wants to ask for an input panel. Qt's
|
|
input widgets do this automatically. If we receive that type of
|
|
event, we call \c updatePosition() \mdash we'll see later on what it
|
|
does \mdash then show the actual input panel widget. If we receive
|
|
the \c CloseSoftwareInputPanel event, we do the opposite, and
|
|
hide the input panel.
|
|
|
|
\snippet examples/tools/inputpanel/myinputpanelcontext.cpp 2
|
|
|
|
We implement the \c sendCharacter() function so that it sends the
|
|
supplied character to the focused widget. All QInputContext based
|
|
classes are always supposed to send events to the widget returned
|
|
by QInputContext::focusWidget(). Note the QPointer guards to make
|
|
sure that the widget does not get destroyed in between events.
|
|
|
|
Also note that we chose to use key press events in this example.
|
|
For more complex use cases with composed text it might be more
|
|
appropriate to send QInputMethodEvent events.
|
|
|
|
The \c updatePosition() function is implemented to position the
|
|
actual input panel window directly below the focused widget.
|
|
|
|
\snippet examples/tools/inputpanel/myinputpanelcontext.cpp 3
|
|
|
|
It performs the positioning by obtaining the coordinates of the
|
|
focused widget and translating them to global coordinates.
|
|
|
|
\section1 MyInputPanel Class Definition
|
|
|
|
The \c MyInputPanel class inherits QWidget and is used to display
|
|
the input panel widget and its buttons.
|
|
|
|
\snippet examples/tools/inputpanel/myinputpanel.h 0
|
|
|
|
If we look at the member variables first, we see that there is
|
|
\c form, which is made with Qt Designer, that contains the layout
|
|
of buttons to click. Note that all the buttons in the layout have
|
|
been declared with the \c NoFocus focus policy so that we can
|
|
maintain focus on the window receiving input instead of the
|
|
window containing buttons.
|
|
|
|
The \c lastFocusedWidget is a helper variable, which also aids in
|
|
maintaining focus.
|
|
|
|
\c signalMapper is an instance of the QSignalMapper class and is
|
|
there to help us tell which button was clicked. Since they are
|
|
all very similar this is a better solution than creating a separate
|
|
slot for each one.
|
|
|
|
The functions that we implement in \c MyInputPanel are the
|
|
following:
|
|
|
|
\list
|
|
\o \c event() is used to intercept and manipulate focus events,
|
|
so we can maintain focus in the main window.
|
|
\o \c saveFocusWidget() is a slot which will be called whenever
|
|
focus changes, and allows us to store the newly focused widget
|
|
in \c lastFocusedWidget, so that its focus can be restored
|
|
if it loses it to the input panel.
|
|
\o \c buttonClicked() is a slot which will be called by the
|
|
\c signalMapper whenever it receives a \c clicked() signal
|
|
from any of the buttons.
|
|
\endlist
|
|
|
|
\section1 MyInputPanel Class Implementation
|
|
|
|
If we look at the constructor first, we have a lot of signals to
|
|
connect to!
|
|
|
|
We connect the QApplication::focusChanged() signal
|
|
to the \c saveFocusWidget() signal in order to get focus updates.
|
|
Then comes the interesting part with the signal mapper: the
|
|
series of \c setMapping() calls sets the mapper up so that each
|
|
signal from one of the buttons will result in a
|
|
QSignalMapper::mapped() signal, with the given widget as a
|
|
parameter. This allows us to do general processing of clicks.
|
|
|
|
\snippet examples/tools/inputpanel/myinputpanel.cpp 0
|
|
|
|
The next series of connections then connect each button's
|
|
\c clicked() signal to the signal mapper. Finally, we create
|
|
a connection from the \c mapped() signal to the
|
|
\c buttonClicked() slot, where we will handle it.
|
|
|
|
\snippet examples/tools/inputpanel/myinputpanel.cpp 3
|
|
|
|
In the \c buttonClicked() slot, we extract the value of the
|
|
"buttonValue" property. This is a custom property which was
|
|
created in Qt Designer and set to the character that we wish the
|
|
button to produce. Then we emit the \c characterGenerated()
|
|
signal, which \c MyInputPanelContext is connected to. This will
|
|
in turn cause it to send the input to the focused widget.
|
|
|
|
In the \c saveFocusWidget() slot, we test whether the newly
|
|
focused widget is a child of the input panel or not, using the
|
|
QWidget::isAncestorOf() call.
|
|
|
|
\snippet examples/tools/inputpanel/myinputpanel.cpp 2
|
|
|
|
If it isn't, it means that the widget is outside the input panel,
|
|
and we store a pointer to that widget for later.
|
|
|
|
In the \c event() function we handle QEvent::WindowActivate
|
|
event, which occurs if the focus switches to the input panel.
|
|
|
|
\snippet examples/tools/inputpanel/myinputpanel.cpp 1
|
|
|
|
Since we want avoid focus on the input panel, we immediately call
|
|
QWidget::activateWindow() on the widget that last had focus, so
|
|
that input into that widget can continue. We ignore any other events
|
|
that we receive.
|
|
|
|
\section1 Setting the Input Context
|
|
|
|
The main function for the example is very similar to those for other
|
|
examples. The only real difference is that it creates a
|
|
\c MyInputPanelContext and sets it as the application-wide input
|
|
context.
|
|
|
|
\snippet examples/tools/inputpanel/main.cpp main
|
|
|
|
With the input context in place, we set up and show the user interface
|
|
made in Qt Designer before running the event loop.
|
|
|
|
\section1 Further Reading
|
|
|
|
This example shows a specific kind of input context that uses interaction
|
|
with a widget to provide input for another. Qt's input context system can
|
|
also be used to create other kinds of input methods. We recommend starting
|
|
with the QInputContext documentation if you want to explore further.
|
|
*/
|