|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 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:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 /*! |
|
43 \example tools/inputpanel |
|
44 \title Input Panel Example |
|
45 |
|
46 The Input Panel example shows how to create an input panel that |
|
47 can be used to input text into widgets using only the pointer and |
|
48 no keyboard. |
|
49 |
|
50 \image inputpanel-example.png |
|
51 |
|
52 The input fields in the main window have no function other than |
|
53 to accept input. The main focus is on how the extra input panel |
|
54 can be used to input text without the need for a real keyboard or |
|
55 keypad. |
|
56 |
|
57 \section1 Main Form Class Definition |
|
58 |
|
59 Because the main window has no other function than to accept |
|
60 input, it has no class definition. Instead, its whole layout is |
|
61 made in Qt Designer. This emphasizes the point that no widget |
|
62 specific code is needed to use input panels with Qt. |
|
63 |
|
64 \section1 MyInputPanelContext Class Definition |
|
65 |
|
66 \snippet examples/tools/inputpanel/myinputpanelcontext.h 0 |
|
67 |
|
68 The \c MyInputPanelContext class inherits QInputContext, which is |
|
69 Qt's base class for handling input methods. |
|
70 \c MyInputPanelContext is responsible for managing the state of |
|
71 the input panel and sending input method events to the receiving |
|
72 widgets. |
|
73 |
|
74 The \c inputPanel member is a pointer to the input panel widget |
|
75 itself; in other words, the window that will display the buttons |
|
76 used for input. |
|
77 |
|
78 The \c identifierName(), \c language(), \c isComposing() and |
|
79 \c reset() functions are there mainly to fill in the pure virtual |
|
80 functions in the base class, QInputContext, but they can be |
|
81 useful in other scenarios. The important functions and slots are |
|
82 the following: |
|
83 |
|
84 \list |
|
85 \o \c filterEvent() is where we receive events telling us to open |
|
86 or close the input panel. |
|
87 \o \c sendCharacter() is a slot which is called when we want to |
|
88 send a character to the focused widget. |
|
89 \o \c updatePosition() is used to position the input panel |
|
90 relative to the focused widget, and will be used when opening |
|
91 the input panel. |
|
92 \endlist |
|
93 |
|
94 \section1 MyInputPanelContext Class Implementation |
|
95 |
|
96 In the constructor we connect to the \c characterGenerated() |
|
97 signal of the input panel, in order to receive key presses. We'll |
|
98 see how it works in detail later on. |
|
99 |
|
100 \snippet examples/tools/inputpanel/myinputpanelcontext.cpp 0 |
|
101 |
|
102 In the \c filterEvent() function, we must look for the two event |
|
103 types: \c RequestSoftwareInputPanel and \c CloseSoftwareInputPanel. |
|
104 |
|
105 \snippet examples/tools/inputpanel/myinputpanelcontext.cpp 1 |
|
106 |
|
107 The first type will be sent whenever |
|
108 an input capable widget wants to ask for an input panel. Qt's |
|
109 input widgets do this automatically. If we receive that type of |
|
110 event, we call \c updatePosition() \mdash we'll see later on what it |
|
111 does \mdash then show the actual input panel widget. If we receive |
|
112 the \c CloseSoftwareInputPanel event, we do the opposite, and |
|
113 hide the input panel. |
|
114 |
|
115 \snippet examples/tools/inputpanel/myinputpanelcontext.cpp 2 |
|
116 |
|
117 We implement the \c sendCharacter() function so that it sends the |
|
118 supplied character to the focused widget. All QInputContext based |
|
119 classes are always supposed to send events to the widget returned |
|
120 by QInputContext::focusWidget(). Note the QPointer guards to make |
|
121 sure that the widget does not get destroyed in between events. |
|
122 |
|
123 Also note that we chose to use key press events in this example. |
|
124 For more complex use cases with composed text it might be more |
|
125 appropriate to send QInputMethodEvent events. |
|
126 |
|
127 The \c updatePosition() function is implemented to position the |
|
128 actual input panel window directly below the focused widget. |
|
129 |
|
130 \snippet examples/tools/inputpanel/myinputpanelcontext.cpp 3 |
|
131 |
|
132 It performs the positioning by obtaining the coordinates of the |
|
133 focused widget and translating them to global coordinates. |
|
134 |
|
135 \section1 MyInputPanel Class Definition |
|
136 |
|
137 The \c MyInputPanel class inherits QWidget and is used to display |
|
138 the input panel widget and its buttons. |
|
139 |
|
140 \snippet examples/tools/inputpanel/myinputpanel.h 0 |
|
141 |
|
142 If we look at the member variables first, we see that there is |
|
143 \c form, which is made with Qt Designer, that contains the layout |
|
144 of buttons to click. Note that all the buttons in the layout have |
|
145 been declared with the \c NoFocus focus policy so that we can |
|
146 maintain focus on the window receiving input instead of the |
|
147 window containing buttons. |
|
148 |
|
149 The \c lastFocusedWidget is a helper variable, which also aids in |
|
150 maintaining focus. |
|
151 |
|
152 \c signalMapper is an instance of the QSignalMapper class and is |
|
153 there to help us tell which button was clicked. Since they are |
|
154 all very similar this is a better solution than creating a separate |
|
155 slot for each one. |
|
156 |
|
157 The functions that we implement in \c MyInputPanel are the |
|
158 following: |
|
159 |
|
160 \list |
|
161 \o \c event() is used to intercept and manipulate focus events, |
|
162 so we can maintain focus in the main window. |
|
163 \o \c saveFocusWidget() is a slot which will be called whenever |
|
164 focus changes, and allows us to store the newly focused widget |
|
165 in \c lastFocusedWidget, so that its focus can be restored |
|
166 if it loses it to the input panel. |
|
167 \o \c buttonClicked() is a slot which will be called by the |
|
168 \c signalMapper whenever it receives a \c clicked() signal |
|
169 from any of the buttons. |
|
170 \endlist |
|
171 |
|
172 \section1 MyInputPanel Class Implementation |
|
173 |
|
174 If we look at the constructor first, we have a lot of signals to |
|
175 connect to! |
|
176 |
|
177 We connect the QApplication::focusChanged() signal |
|
178 to the \c saveFocusWidget() signal in order to get focus updates. |
|
179 Then comes the interesting part with the signal mapper: the |
|
180 series of \c setMapping() calls sets the mapper up so that each |
|
181 signal from one of the buttons will result in a |
|
182 QSignalMapper::mapped() signal, with the given widget as a |
|
183 parameter. This allows us to do general processing of clicks. |
|
184 |
|
185 \snippet examples/tools/inputpanel/myinputpanel.cpp 0 |
|
186 |
|
187 The next series of connections then connect each button's |
|
188 \c clicked() signal to the signal mapper. Finally, we create |
|
189 a connection from the \c mapped() signal to the |
|
190 \c buttonClicked() slot, where we will handle it. |
|
191 |
|
192 \snippet examples/tools/inputpanel/myinputpanel.cpp 3 |
|
193 |
|
194 In the \c buttonClicked() slot, we extract the value of the |
|
195 "buttonValue" property. This is a custom property which was |
|
196 created in Qt Designer and set to the character that we wish the |
|
197 button to produce. Then we emit the \c characterGenerated() |
|
198 signal, which \c MyInputPanelContext is connected to. This will |
|
199 in turn cause it to send the input to the focused widget. |
|
200 |
|
201 In the \c saveFocusWidget() slot, we test whether the newly |
|
202 focused widget is a child of the input panel or not, using the |
|
203 QWidget::isAncestorOf() call. |
|
204 |
|
205 \snippet examples/tools/inputpanel/myinputpanel.cpp 2 |
|
206 |
|
207 If it isn't, it means that the widget is outside the input panel, |
|
208 and we store a pointer to that widget for later. |
|
209 |
|
210 In the \c event() function we handle QEvent::WindowActivate |
|
211 event, which occurs if the focus switches to the input panel. |
|
212 |
|
213 \snippet examples/tools/inputpanel/myinputpanel.cpp 1 |
|
214 |
|
215 Since we want avoid focus on the input panel, we immediately call |
|
216 QWidget::activateWindow() on the widget that last had focus, so |
|
217 that input into that widget can continue. We ignore any other events |
|
218 that we receive. |
|
219 |
|
220 \section1 Setting the Input Context |
|
221 |
|
222 The main function for the example is very similar to those for other |
|
223 examples. The only real difference is that it creates a |
|
224 \c MyInputPanelContext and sets it as the application-wide input |
|
225 context. |
|
226 |
|
227 \snippet examples/tools/inputpanel/main.cpp main |
|
228 |
|
229 With the input context in place, we set up and show the user interface |
|
230 made in Qt Designer before running the event loop. |
|
231 |
|
232 \section1 Further Reading |
|
233 |
|
234 This example shows a specific kind of input context that uses interaction |
|
235 with a widget to provide input for another. Qt's input context system can |
|
236 also be used to create other kinds of input methods. We recommend starting |
|
237 with the QInputContext documentation if you want to explore further. |
|
238 */ |