|
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 designer/taskmenuextension |
|
44 \title Task Menu Extension Example |
|
45 |
|
46 The Task Menu Extension example shows how to create a custom |
|
47 widget plugin for \l {Qt Designer Manual}{\QD}, and how to to use |
|
48 the QDesignerTaskMenuExtension class to provide custom task menu |
|
49 entries associated with the plugin. |
|
50 |
|
51 \image taskmenuextension-example-faded.png |
|
52 |
|
53 To provide a custom widget that can be used with \QD, we need to |
|
54 supply a self-contained implementation. In this example we use a |
|
55 custom widget designed to show the task menu extension feature: |
|
56 The TicTacToe widget. |
|
57 |
|
58 An extension is an object which modifies the behavior of \QD. The |
|
59 QDesignerTaskMenuExtension can provide custom task menu entries |
|
60 when a widget with this extension is selected. |
|
61 |
|
62 There are four available types of extensions in \QD: |
|
63 |
|
64 \list |
|
65 \o QDesignerContainerExtension provides an extension that allows |
|
66 you to add (and delete) pages to a multi-page container plugin |
|
67 in \QD. |
|
68 \o QDesignerMemberSheetExtension provides an extension that allows |
|
69 you to manipulate a widget's member functions which is displayed |
|
70 when configuring connections using Qt Designer's mode for editing |
|
71 signals and slots. |
|
72 \o QDesignerPropertySheetExtension provides an extension that |
|
73 allows you to manipulate a widget's properties which is displayed |
|
74 in Qt Designer's property editor. |
|
75 \o QDesignerTaskMenuExtension provides an extension that allows |
|
76 you to add custom menu entries to \QD's task menu. |
|
77 \endlist |
|
78 |
|
79 You can use all the extensions following the same pattern as in |
|
80 this example, only replacing the respective extension base |
|
81 class. For more information, see the \l {QtDesigner Module}. |
|
82 |
|
83 The Task Menu Extension example consists of five classes: |
|
84 |
|
85 \list |
|
86 \o \c TicTacToe is a custom widget that lets the user play |
|
87 the Tic-Tac-Toe game. |
|
88 \o \c TicTacToePlugin exposes the \c TicTacToe class to \QD. |
|
89 \o \c TicTacToeTaskMenuFactory creates a \c TicTacToeTaskMenu object. |
|
90 \o \c TicTacToeTaskMenu provides the task menu extension, i.e the |
|
91 plugin's associated task menu entries. |
|
92 \o \c TicTacToeDialog lets the user modify the state of a |
|
93 Tic-Tac-Toe plugin loaded into \QD. |
|
94 \endlist |
|
95 |
|
96 The project file for custom widget plugins needs some additional |
|
97 information to ensure that they will work within \QD. For example, |
|
98 custom widget plugins rely on components supplied with \QD, and |
|
99 this must be specified in the project file that we use. We will |
|
100 first take a look at the plugin's project file. |
|
101 |
|
102 Then we will continue by reviewing the \c TicTacToePlugin class, |
|
103 and take a look at the \c TicTacToeTaskMenuFactory and \c |
|
104 TicTacToeTaskMenu classes. Finally, we will review the \c |
|
105 TicTacToeDialog class before we take a quick look at the \c |
|
106 TicTacToe widget's class definition. |
|
107 |
|
108 \section1 The Project File: taskmenuextension.pro |
|
109 |
|
110 The project file must contain some additional information to |
|
111 ensure that the plugin will work as expected: |
|
112 |
|
113 \snippet examples/designer/taskmenuextension/taskmenuextension.pro 0 |
|
114 \snippet examples/designer/taskmenuextension/taskmenuextension.pro 1 |
|
115 |
|
116 The \c TEMPLATE variable's value makes \c qmake create the custom |
|
117 widget as a library. Later, we will ensure that the widget will be |
|
118 recognized as a plugin by Qt by using the Q_EXPORT_PLUGIN2() macro to |
|
119 export the relevant widget information. |
|
120 |
|
121 The \c CONFIG variable contains two values, \c designer and \c |
|
122 plugin: |
|
123 |
|
124 \list |
|
125 \o \c designer: Since custom widgets plugins rely on components |
|
126 supplied with \QD, this value ensures that our plugin links against |
|
127 \QD's library (\c libQtDesigner.so). |
|
128 |
|
129 \o \c plugin: We also need to ensure that \c qmake considers the |
|
130 custom widget a \e plugin library. |
|
131 \endlist |
|
132 |
|
133 When Qt is configured to build in both debug and release modes, |
|
134 \QD will be built in release mode. When this occurs, it is |
|
135 necessary to ensure that plugins are also built in release |
|
136 mode. For that reason we add the \c debug_and_release value to |
|
137 the \c CONFIG variable. Otherwise, if a plugin is built in a mode |
|
138 that is incompatible with \QD, it won't be loaded and |
|
139 installed. |
|
140 |
|
141 The header and source files for the widget are declared in the |
|
142 usual way: |
|
143 |
|
144 \snippet examples/designer/taskmenuextension/taskmenuextension.pro 2 |
|
145 |
|
146 We provide an implementation of the plugin interface so that \QD |
|
147 can use the custom widget. In this particular example we also |
|
148 provide implementations of the task menu extension and the |
|
149 extension factory as well as a dialog implementation. |
|
150 |
|
151 It is important to ensure that the plugin is installed in a |
|
152 location that is searched by \QD. We do this by specifying a |
|
153 target path for the project and adding it to the list of items to |
|
154 install: |
|
155 |
|
156 \snippet doc/src/snippets/code/doc_src_examples_taskmenuextension.qdoc 0 |
|
157 |
|
158 The task menu extension is created as a library, and will be |
|
159 installed alongside the other \QD plugins when the project is |
|
160 installed (using \c{make install} or an equivalent installation |
|
161 procedure). |
|
162 |
|
163 Note that if you want the plugins to appear in a Visual Studio |
|
164 integration, the plugins must be built in release mode and their |
|
165 libraries must be copied into the plugin directory in the install |
|
166 path of the integration (for an example, see \c {C:/program |
|
167 files/trolltech as/visual studio integration/plugins}). |
|
168 |
|
169 For more information about plugins, see the \l {How to Create Qt |
|
170 Plugins} documentation. |
|
171 |
|
172 \section1 TicTacToePlugin Class Definition |
|
173 |
|
174 The \c TicTacToePlugin class exposes \c the TicTacToe class to |
|
175 \QD. Its definition is equivalent to the \l |
|
176 {designer/customwidgetplugin}{Custom Widget Plugin} example's |
|
177 plugin class which is explained in detail. The only part of the |
|
178 class definition that is specific to this particular custom widget |
|
179 is the class name: |
|
180 |
|
181 \snippet examples/designer/taskmenuextension/tictactoeplugin.h 0 |
|
182 |
|
183 The plugin class provides \QD with basic information about our |
|
184 plugin, such as its class name and its include file. Furthermore |
|
185 it knows how to create instances of the \c TicTacToe widget. |
|
186 TicTacToePlugin also defines the \l |
|
187 {QDesignerCustomWidgetInterface::initialize()}{initialize()} |
|
188 function which is called after the plugin is loaded into \QD. The |
|
189 function's QDesignerFormEditorInterface parameter provides the |
|
190 plugin with a gateway to all of \QD's API's. |
|
191 |
|
192 The \c TicTacToePlugin class inherits from both QObject and |
|
193 QDesignerCustomWidgetInterface. It is important to remember, when |
|
194 using multiple inheritance, to ensure that all the interfaces |
|
195 (i.e. the classes that doesn't inherit Q_OBJECT) are made known to |
|
196 the meta object system using the Q_INTERFACES() macro. This |
|
197 enables \QD to use \l qobject_cast() to query for supported |
|
198 interfaces using nothing but a QObject pointer. |
|
199 |
|
200 \section1 TicTacToePlugin Class Implementation |
|
201 |
|
202 The TicTacToePlugin class implementation is in most parts |
|
203 equivalent to the \l {designer/customwidgetplugin}{Custom Widget |
|
204 Plugin} example's plugin class: |
|
205 |
|
206 \snippet examples/designer/taskmenuextension/tictactoeplugin.cpp 0 |
|
207 |
|
208 The only function that differs significantly is the initialize() |
|
209 function: |
|
210 |
|
211 \snippet examples/designer/taskmenuextension/tictactoeplugin.cpp 1 |
|
212 |
|
213 The \c initialize() function takes a QDesignerFormEditorInterface |
|
214 object as argument. The QDesignerFormEditorInterface class |
|
215 provides access to Qt Designer's components. |
|
216 |
|
217 In \QD you can create two kinds of plugins: custom widget plugins |
|
218 and tool plugins. QDesignerFormEditorInterface provides access to |
|
219 all the \QD components that you normally need to create a tool |
|
220 plugin: the extension manager, the object inspector, the property |
|
221 editor and the widget box. Custom widget plugins have access to |
|
222 the same components. |
|
223 |
|
224 \snippet examples/designer/taskmenuextension/tictactoeplugin.cpp 2 |
|
225 |
|
226 When creating extensions associated with custom widget plugins, we |
|
227 need to access \QD's current extension manager which we retrieve |
|
228 from the QDesignerFormEditorInterface parameter. |
|
229 |
|
230 \QD's QDesignerFormEditorInterface holds information about all Qt |
|
231 Designer's components: The action editor, the object inspector, |
|
232 the property editor, the widget box, and the extension and form |
|
233 window managers. |
|
234 |
|
235 The QExtensionManager class provides extension management |
|
236 facilities for \QD. Using \QD's current extension manager you can |
|
237 retrieve the extension for a given object. You can also register |
|
238 and unregister an extension for a given object. Remember that an |
|
239 extension is an object which modifies the behavior of \QD. |
|
240 |
|
241 When registrering an extension, it is actually the associated |
|
242 extension factory that is registered. In \QD, extension factories |
|
243 are used to look up and create named extensions as they are |
|
244 required. So, in this example, the task menu extension itself is |
|
245 not created until a task menu is requested by the user. |
|
246 |
|
247 \snippet examples/designer/taskmenuextension/tictactoeplugin.cpp 3 |
|
248 |
|
249 We create a \c TicTacToeTaskMenuFactory object that we register |
|
250 using \QD's current \l {QExtensionManager}{extension manager} |
|
251 retrieved from the QDesignerFormEditorInterface parameter. The |
|
252 first argument is the newly created factory and the second |
|
253 argument is an extension identifier which is a string. The \c |
|
254 Q_TYPEID() macro simply converts the string into a QLatin1String. |
|
255 |
|
256 The \c TicTacToeTaskMenuFactory class is a subclass of |
|
257 QExtensionFactory. When the user request a task menu by clicking |
|
258 the right mouse button over a widget with the specified task menu |
|
259 extension, \QD's extension manager will run through all its |
|
260 registered factories invoking the first one that is able to create |
|
261 a task menu extension for the selected widget. This factory will |
|
262 in turn create a \c TicTacToeTaskMenu object (the extension). |
|
263 |
|
264 We omit to reimplement the |
|
265 QDesignerCustomWidgetInterface::domXml() function (which include |
|
266 default settings for the widget in the standard XML format used by |
|
267 Qt Designer), since no default values are necessary. |
|
268 |
|
269 \snippet examples/designer/taskmenuextension/tictactoeplugin.cpp 4 |
|
270 |
|
271 Finally, we use the Q_EXPORT_PLUGIN2() macro to export the |
|
272 TicTacToePlugin class for use with Qt's plugin handling classes: |
|
273 This macro ensures that \QD can access and construct the custom |
|
274 widget. Without this macro, there is no way for \QD to use the |
|
275 widget. |
|
276 |
|
277 \section1 TicTacToeTaskMenuFactory Class Definition |
|
278 |
|
279 The \c TicTacToeTaskMenuFactory class inherits QExtensionFactory |
|
280 which provides a standard extension factory for \QD. |
|
281 |
|
282 \snippet examples/designer/taskmenuextension/tictactoetaskmenu.h 1 |
|
283 |
|
284 The subclass's purpose is to reimplement the |
|
285 QExtensionFactory::createExtension() function, making it able to |
|
286 create a \c TicTacToe task menu extension. |
|
287 |
|
288 \section1 TicTacToeTaskMenuFactory Class Implementation |
|
289 |
|
290 The class constructor simply calls the QExtensionFactory base |
|
291 class constructor: |
|
292 |
|
293 \snippet examples/designer/taskmenuextension/tictactoetaskmenu.cpp 4 |
|
294 |
|
295 As described above, the factory is invoked when the user request a |
|
296 task menu by clicking the right mouse button over a widget with |
|
297 the specified task menu extension in \QD. |
|
298 |
|
299 \QD's behavior is the same whether the requested extension is |
|
300 associated with a container, a member sheet, a property sheet or a |
|
301 task menu: Its extension manager runs through all its registered |
|
302 extension factories calling \c createExtension() for each until |
|
303 one responds by creating the requested extension. |
|
304 |
|
305 \snippet examples/designer/taskmenuextension/tictactoetaskmenu.cpp 5 |
|
306 |
|
307 So the first thing we do in \c |
|
308 TicTacToeTaskMenuFactory::createExtension() is to check if the |
|
309 requested extension is a task menu extension. If it is, and the |
|
310 widget requesting it is a \c TicTacToe widget, we create and |
|
311 return a \c TicTacToeTaskMenu object. Otherwise, we simply return |
|
312 a null pointer, allowing \QD's extension manager to continue its |
|
313 search through the registered factories. |
|
314 |
|
315 |
|
316 \section1 TicTacToeTaskMenu Class Definition |
|
317 |
|
318 \image taskmenuextension-menu.png |
|
319 |
|
320 The \c TicTacToeTaskMenu class inherits QDesignerTaskMenuExtension |
|
321 which allows you to add custom entries (in the form of QActions) |
|
322 to the task menu in \QD. |
|
323 |
|
324 \snippet examples/designer/taskmenuextension/tictactoetaskmenu.h 0 |
|
325 |
|
326 We reimplement the \c preferredEditAction() and \c taskActions() |
|
327 functions. Note that we implement a constructor that takes \e two |
|
328 arguments: the parent widget, and the \c TicTacToe widget for |
|
329 which the task menu is requested. |
|
330 |
|
331 In addition we declare the private \c editState() slot, our custom |
|
332 \c editStateAction and a private pointer to the \c TicTacToe |
|
333 widget which state we want to modify. |
|
334 |
|
335 \section1 TicTacToeTaskMenu Class Implementation |
|
336 |
|
337 \snippet examples/designer/taskmenuextension/tictactoetaskmenu.cpp 0 |
|
338 |
|
339 In the constructor we first save the reference to the \c TicTacToe |
|
340 widget sent as parameter, i.e the widget which state we want to |
|
341 modify. We will need this later when our custom action is |
|
342 invoked. We also create our custom \c editStateAction and connect |
|
343 it to the \c editState() slot. |
|
344 |
|
345 \snippet examples/designer/taskmenuextension/tictactoetaskmenu.cpp 1 |
|
346 |
|
347 The \c editState() slot is called whenever the user chooses the |
|
348 \gui {Edit State...} option in a \c TicTacToe widget's task menu. The |
|
349 slot creates a \c TicTacToeDialog presenting the current state of |
|
350 the widget, and allowing the user to edit its state by playing the |
|
351 game. |
|
352 |
|
353 \snippet examples/designer/taskmenuextension/tictactoetaskmenu.cpp 2 |
|
354 |
|
355 We reimplement the \c preferredEditAction() function to return our |
|
356 custom \c editStateAction as the action that should be invoked |
|
357 when selecting a \c TicTacToe widget and pressing \key F2 . |
|
358 |
|
359 \snippet examples/designer/taskmenuextension/tictactoetaskmenu.cpp 3 |
|
360 |
|
361 We reimplement the \c taskActions() function to return a list of |
|
362 our custom actions making these appear on top of the default menu |
|
363 entries in a \c TicTacToe widget's task menu. |
|
364 |
|
365 \section1 TicTacToeDialog Class Definition |
|
366 |
|
367 \image taskmenuextension-dialog.png |
|
368 |
|
369 The \c TicTacToeDialog class inherits QDialog. The dialog lets the |
|
370 user modify the state of the currently selected Tic-Tac-Toe |
|
371 plugin. |
|
372 |
|
373 \snippet examples/designer/taskmenuextension/tictactoedialog.h 0 |
|
374 |
|
375 We reimplement the \c sizeHint() function. We also declare two |
|
376 private slots: \c resetState() and \c saveState(). In addition to |
|
377 the dialog's buttons and layouts we declare two \c TicTacToe |
|
378 pointers, one to the widget the user can interact with and the |
|
379 other to the original custom widget plugin which state the user |
|
380 wants to edit. |
|
381 |
|
382 \section1 TicTacToeDialog Class Implementation |
|
383 |
|
384 \snippet examples/designer/taskmenuextension/tictactoedialog.cpp 0 |
|
385 |
|
386 In the constructor we first save the reference to the TicTacToe |
|
387 widget sent as parameter, i.e the widget which state the user want |
|
388 to modify. Then we create a new \c TicTacToe widget, and set its |
|
389 state to be equivalent to the parameter widget's state. |
|
390 |
|
391 Finally, we create the dialog's buttons and layout. |
|
392 |
|
393 \snippet examples/designer/taskmenuextension/tictactoedialog.cpp 1 |
|
394 |
|
395 We reimplement the \c sizeHint() function to ensure that the |
|
396 dialog is given a reasonable size. |
|
397 |
|
398 \snippet examples/designer/taskmenuextension/tictactoedialog.cpp 2 |
|
399 |
|
400 The \c resetState() slot is called whenever the user press the |
|
401 \gui Reset button. The only thing we do is to call the \c |
|
402 clearBoard() function for the editor widget, i.e. the \c TicTacToe |
|
403 widget we created in the dialog's constructor. |
|
404 |
|
405 \snippet examples/designer/taskmenuextension/tictactoedialog.cpp 3 |
|
406 |
|
407 The \c saveState() slot is called whenever the user press the \gui |
|
408 OK button, and transfers the state of the editor widget to the |
|
409 widget which state we want to modify. In order to make the change |
|
410 of state visible to \QD we need to set the latter widget's state |
|
411 property using the QDesignerFormWindowInterface class. |
|
412 |
|
413 QDesignerFormWindowInterface provides you with information about |
|
414 the associated form window as well as allowing you to alter its |
|
415 properties. The interface is not intended to be instantiated |
|
416 directly, but to provide access to Qt Designer's current form |
|
417 windows controlled by Qt Designer's form window manager. |
|
418 |
|
419 If you are looking for the form window containing a specific |
|
420 widget, you can use the static |
|
421 QDesignerFormWindowInterface::findFormWindow() function: |
|
422 |
|
423 \snippet examples/designer/taskmenuextension/tictactoedialog.cpp 4 |
|
424 |
|
425 After retrieving the form window of the widget (which state we |
|
426 want to modify), we use the QDesignerFormWindowInterface::cursor() |
|
427 function to retrieve the form window's cursor. |
|
428 |
|
429 The QDesignerFormWindowCursorInterface class provides an interface |
|
430 to the form window's text cursor. Once we have cursor, we can |
|
431 finally set the state property using the |
|
432 QDesignerFormWindowCursorInterface::setProperty() function. |
|
433 |
|
434 \snippet examples/designer/taskmenuextension/tictactoedialog.cpp 5 |
|
435 |
|
436 In the end we call the QEvent::accept() function which sets the |
|
437 accept flag of the event object. Setting the \c accept parameter |
|
438 indicates that the event receiver wants the event. Unwanted events |
|
439 might be propagated to the parent widget. |
|
440 |
|
441 \section1 TicTacToe Class Definition |
|
442 |
|
443 The \c TicTacToe class is a custom widget that lets the user play |
|
444 the Tic-Tac-Toe game. |
|
445 |
|
446 \snippet examples/designer/taskmenuextension/tictactoe.h 0 |
|
447 |
|
448 The main details to observe in the \c TicTacToe class defintion is |
|
449 the declaration of the \c state property and its \c state() and \c |
|
450 setState() functions. |
|
451 |
|
452 We need to declare the \c TicTacToe widget's state as a property |
|
453 to make it visible to \QD; allowing \QD to manage it in the same |
|
454 way it manages the properties the \c TicTacToe widget inherits |
|
455 from QWidget and QObject, for example featuring the property |
|
456 editor. |
|
457 */ |