source: trunk/doc/src/frameworks-technologies/dbus-adaptors.qdoc@ 561

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 20.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \page usingadaptors.html
44 \title Using QtDBus Adaptors
45
46 \ingroup best-practices
47
48 Adaptors are special classes that are attached to any QObject-derived class
49 and provide the interface to the external world using D-Bus. Adaptors are
50 intended to be lightweight classes whose main purpose is to relay calls to
51 and from the real object, possibly validating or converting the input from
52 the external world and, thus, protecting the real object.
53
54 Unlike multiple inheritance, adaptors can be added at any time to any object
55 (but not removed), which allows for greater flexibility when exporting
56 existing classes. Another advantage of adaptors is to provide similar but not
57 identical functionality in methods of the same name in different interfaces,
58 a case which can be quite common when adding a new version of a standard
59 interface to an object.
60
61 In order to use an adaptor, one must create a class which inherits
62 QDBusAbstractAdaptor. Since that is a standard QObject-derived class, the
63 Q_OBJECT macro must appear in the declaration and the source file must be
64 processed with the \l {moc} tool. The class must also contain one
65 Q_CLASSINFO entry with the \c {"D-Bus Interface"} name, declaring which
66 interface it is exporting. Only one entry per class is supported.
67
68 Any public slot in the class will be accessible through the bus over messages
69 of the MethodCall type. (See \l {Declaring Slots in D-Bus Adaptors} for more
70 information). Signals in the class will be automatically relayed over D-Bus.
71 However, not all types are allowed signals or slots' parameter lists: see
72 \l {The QtDBus Type System} for more information.
73
74 Also, any property declared with Q_PROPERTY will be automatically exposed
75 over the Properties interface on D-Bus. Since the QObject property system
76 does not allow for non-readable properties, it is not possible to declare
77 write-only properties using adaptors.
78
79 More information:
80 \list
81 \o \l{Declaring Slots in D-Bus Adaptors}
82 \o \l{Declaring Signals in D-Bus Adaptors}
83 \o \l{The QtDBus Type System}
84 \o \l{D-Bus Adaptor Example}
85 \endlist
86
87 \sa QDBusAbstractAdaptor
88*/
89
90/*!
91 \page qdbusadaptorexample.html
92 \title D-Bus Adaptor Example
93
94 \previouspage The QtDBus Type System
95 \contentspage Using QtDBus Adaptors
96
97 The following example code shows how a D-Bus interface can be implemented
98 using an adaptor.
99
100 A sample usage of QDBusAbstractAdaptor is as follows:
101 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 0
102
103 The code above would create an interface that could be represented more or less in the following
104 canonical representation:
105 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 1
106
107 This adaptor could be used in the application's main function as follows
108 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 2
109
110 Break-down analysis:
111 \tableofcontents
112
113 \section1 The header
114
115 The header of the example is:
116 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 3
117
118 The code does the following:
119 \list
120 \o it declares the adaptor MainApplicationAdaptor, which descends from QDBusAbstractAdaptor
121 \o it declares the Qt meta-object data using the Q_OBJECT macro
122 \o it declares the name of the D-Bus interface it implements.
123 \endlist
124
125 \section1 The properties
126
127 The properties are declared as follows:
128 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 4
129
130 And are implemented as follows:
131 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 5
132
133 The code declares three properties: one of them is a read-write property called "caption" of
134 string type. The other two are read-only, also of the string type.
135
136 The properties organizationName and organizationDomain are simple relays of the app object's
137 organizationName and organizationDomain properties. However, the caption property requires
138 verifying if the application has a main window associated with it: if there isn't any, the
139 caption property is empty. Note how it is possible to access data defined in other objects
140 through the getter/setter functions.
141
142 \section1 The constructor
143
144 The constructor:
145 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 6
146
147 The constructor does the following:
148 \list
149 \o it initialises its base class (QDBusAbstractAdaptor) with the parent object it is related to.
150 \o it stores the app pointer in a member variable. Note that it would be possible to access the
151 same object using the QDBusAbstractAdaptor::object() function, but it would be necessary to
152 use \a static_cast<> to properly access the methods in QApplication that are not part of
153 QObject.
154 \o it connects the application's signal \a aboutToQuit to its own signal \a aboutToQuit.
155 \o it connects the application's signal \a focusChanged to a private slot to do some further
156 processing before emitting a D-Bus signal.
157 \endlist
158
159 Note that there is no destructor in the example. An eventual destructor could be used to emit
160 one last signal before the object is destroyed, for instance.
161
162 \section1 Slots/methods
163
164 The public slots in the example (which will be exported as D-Bus methods) are the following:
165 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 7
166
167 This snippet of code defines 4 methods with different properties each:
168 \list 1
169 \o \c quit: this method takes no parameters and is defined to be asynchronous. That is, callers
170 are expected to use "fire-and-forget" mechanism when calling this method, since it provides no
171 useful reply. This is represented in D-Bus by the use of the
172 org.freedesktop.DBus.Method.NoReply annotation. See \l Q_NOREPLY for more information on
173 asynchronous methods
174
175 \o \c reparseConfiguration: this simple method, with no input or output arguments simply relays
176 the call to the application's reparseConfiguration member function.
177
178 \o \c mainWindowObject: this method takes no input parameter, but returns one string output
179 argument, containing the path to the main window object (if the application has a main
180 window), or an empty string if it has no main window. Note that this method could have also
181 been written: void mainWindowObject(QString &path).
182
183 \o \c setSessionManagement: this method takes one input argument (a boolean) and, depending on
184 its value, it calls one function or another in the application.
185 \endlist
186
187 See also: \l Q_NOREPLY.
188
189 \section1 Signals
190
191 The signals in this example are defined as follows:
192 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 8
193
194 However, signal definition isn't enough: signals have to be emitted. One simple way of emitting
195 signals is to connect another signal to them, so that Qt's signal handling system chains them
196 automatically. This is what is done for the \a aboutToQuit signal.
197
198 When this is the case, one can use the QDBusAbstractAdaptor::setAutoRelaySignals to
199 automatically connect every signal from the real object to the adaptor.
200
201 When simple signal-to-signal connection isn't enough, one can use a private slot do do some
202 work. This is what was done for the mainWindowHasFocus signal:
203 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 9
204
205 This private slot (which will not be exported as a method via D-Bus) was connected to the
206 \c focusChanged signal in the adaptor's constructor. It is therefore able to shape the
207 application's signal into what the interface expects it to be.
208*/
209
210/*!
211 \page qdbusdeclaringslots.html
212 \title Declaring Slots in D-Bus Adaptors
213
214 \contentspage Using QtDBus Adaptors
215 \nextpage Declaring Signals in D-Bus Adaptors
216
217 Slots in D-Bus adaptors are declared just like normal, public slots, but their
218 parameters must follow certain rules (see \l{The QtDBus Type System} for more
219 information). Slots whose parameters do not follow those rules or that are not
220 public will not be accessible via D-Bus.
221
222 Slots can have one parameter of type \c{const QDBusMessage &}, which must
223 appear at the end of the input parameter list, before any output parameters.
224 This parameter, if present, will be initialized with a copy of the
225 current message being processed, which allows the callee to obtain
226 information about the caller, such as its connection name.
227
228 Slots can be of three kinds:
229 \list 1
230 \o Asynchronous
231 \o Input-only
232 \o Input-and-output
233 \endlist
234
235 \section1 Asynchronous Slots
236 Asynchronous slots are those that do not normally return any reply to the
237 caller. For that reason, they cannot take any output parameters. In most
238 cases, by the time the first line of the slot is run, the caller function
239 has already resumed working.
240
241 However, slots must not rely on that behavior. Scheduling and message-dispatching
242 issues could change the order in which the slot is run. Code intending to
243 synchronize with the caller should provide its own method of synchronization.
244
245 Asynchronous slots are marked by the keyword \l Q_NOREPLY in the method
246 signature, before the \c void return type and the slot name. (See the
247 \c quit() slot in the \l{D-Bus Adaptor Example}).
248
249 \section1 Input-Only Slots
250
251 Input-only slots are normal slots that take parameters passed by value or
252 by constant reference. However, unlike asynchronous slots, the caller is
253 usually waiting for completion of the callee before resuming operation.
254 Therefore, non-asynchronous slots should not block or should state it its
255 documentation that they may do so.
256
257 Input-only slots have no special marking in their signature, except that
258 they take only parameters passed by value or by constant reference.
259 Optionally, slots can take a QDBusMessage parameter as a last parameter,
260 which can be used to perform additional analysis of the method call message.
261
262 \section1 Input and Output Slots
263
264 Like input-only slots, input-and-output slots are those that the caller is
265 waiting for a reply. Unlike input-only ones, though, this reply will contain
266 data. Slots that output data may contain non-constant references and may
267 return a value as well. However, the output parameters must all appear at
268 the end of the argument list and may not have input arguments interleaved.
269 Optionally, a QDBusMessage argument may appear between the input and the
270 output arguments.
271
272 \section1 Automatic Replies
273
274 Method replies are generated automatically with the contents of the output
275 parameters (if there were any) by the QtDBus implementation. Slots need not
276 worry about constructing proper QDBusMessage objects and sending them over
277 the connection.
278
279 However, the possibility of doing so remains there. Should the slot find out
280 it needs to send a special reply or even an error, it can do so by using
281 QDBusMessage::createReply() or QDBusMessage::createErrorReply() on the
282 QDBusMessage parameter and send it with QDBusConnection::send(). The
283 QtDBus implementation will not generate any reply if the slot did so.
284
285 \warning When a caller places a method call and waits for a reply, it will
286 only wait for a limited amount of time. Slots intending to take a long time
287 to complete should make that fact clear in documentation so that callers
288 properly set higher timeouts.
289
290 \section1 Delayed Replies
291
292 In some circumstances, the called slot may not be able to process
293 the request immediately. This is frequently the case when the
294 request involves an I/O or networking operation which may block.
295
296 If this is the case, the slot should return control to the
297 application's main loop to avoid freezing the user interface, and
298 resume the process later. To accomplish this, it should make use
299 of the extra \c QDBusMessage parameter at the end of the input
300 parameter list and request a delayed reply.
301
302 We do this by writing a slot that stores the request data in a
303 persistent structure, indicating to the caller using
304 \l{QDBusMessage::setDelayedReply()}{QDBusMessage::setDelayedReply(true)}
305 that the response will be sent later.
306
307 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 10
308
309 The use of
310 \l{QDBusConnection::send()}{QDBusConnection::sessionBus().send(data->reply)}
311 is needed to explicitly inform the caller that the response will be delayed.
312 In this case, the return value is unimportant; we return an arbitrary value
313 to satisfy the compiler.
314
315 When the request is processed and a reply is available, it should be sent
316 using the \c QDBusMessage object that was obtained. In our example, the
317 reply code could be something as follows:
318
319 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 11
320
321 As can be seen in the example, when a delayed reply is in place,
322 the return value(s) from the slot will be ignored by QtDBus. They
323 are used only to determine the slot's signature when communicating
324 the adaptor's description to remote applications, or in case the
325 code in the slot decides not to use a delayed reply.
326
327 The delayed reply itself is requested from QtDBus by calling
328 QDBusMessage::reply() on the original message. It then becomes the
329 resposibility of the called code to eventually send a reply to the
330 caller.
331
332 \warning When a caller places a method call and waits for a reply, it will
333 only wait for a limited amount of time. Slots intending to take a long time
334 to complete should make that fact clear in documentation so that callers
335 properly set higher timeouts.
336
337 \sa {Using QtDBus Adaptors}, {Declaring Signals in D-Bus Adaptors},
338 {The QtDBus Type System}, QDBusConnection, QDBusMessage
339*/
340
341/*!
342 \page qdbusdeclaringsignals.html
343 \title Declaring Signals in D-Bus Adaptors
344
345 \previouspage Declaring Slots in D-Bus Adaptors
346 \contentspage Using QtDBus Adaptors
347 \nextpage The QtDBus Type System
348
349 Any signal in a class derived from QDBusAbstractAdaptor will be automatically
350 relayed into D-Bus, provided that the signal's parameters conform to certain
351 rules (see \l{The QtDBus Type System} for more information). No special code
352 is necessary to make this relay.
353
354 However, signals must still be emitted. The easiest way to emit an adaptor
355 signal is to connect another signal to it, so that Qt's signals and slots
356 mechanism automatically emits the adaptor signal, too. This can be done in
357 the adaptor's constructor, as has been done in the
358 \l{D-Bus Adaptor Example}{D-Bus Adaptor example}.
359
360 The QDBusAbstractAdaptor::setAutoRelaySignals() convenience function can also
361 be used to make and break connections between signals in the real object and
362 the corresponding signals in the adaptor. It will inspect the list of signals
363 in both classes and connect those whose parameters match exactly.
364
365 \sa {Using QtDBus Adaptors},
366 {Declaring Slots in D-Bus Adaptors},
367 {The QtDBus Type System}, QDBusAbstractAdaptor
368*/
369
370/*!
371 \page qdbustypesystem.html
372 \title The QtDBus Type System
373
374 \previouspage Declaring Signals in D-Bus Adaptors
375 \contentspage Using QtDBus Adaptors
376 \nextpage D-Bus Adaptor Example
377
378 D-Bus has an extensible type system based on a few primitives and
379 composition of the primitives in arrays and structures. QtDBus
380 implements the interface to that type system through the
381 QDBusArgument class, allowing user programs to send and receive
382 practically every C++ type over the bus.
383
384 \section1 Primitive Types
385
386 The primitive types are supported natively by QDBusArgument and
387 need no special customization to be sent or received. They are
388 listed below, along with the C++ class they relate to:
389
390 \table
391 \header
392 \o Qt type
393 \o D-Bus equivalent type
394 \row
395 \o uchar
396 \o BYTE
397 \row
398 \o bool
399 \o BOOLEAN
400 \row
401 \o short
402 \o INT16
403 \row
404 \o ushort
405 \o UINT16
406 \row
407 \o int
408 \o INT32
409 \row
410 \o uint
411 \o UINT32
412 \row
413 \o qlonglong
414 \o INT64
415 \row
416 \o qulonglong
417 \o UINT64
418 \row
419 \o double
420 \o DOUBLE
421 \row
422 \o QString
423 \o STRING
424 \row
425 \o QDBusVariant
426 \o VARIANT
427 \row
428 \o QDBusObjectPath
429 \o OBJECT_PATH
430 \row
431 \o QDBusSignature
432 \o SIGNATURE
433 \endtable
434
435 Aside from the primitive types, QDBusArgument also supports two
436 non-primitive types natively, due to their widespread use in Qt
437 applications: QStringList and QByteArray.
438
439 \section1 Compound Types
440
441 D-Bus specifies three types of aggregations of primitive types
442 that allow one to create compound types. They are \c ARRAY, \c
443 STRUCT and maps/dictionaries.
444
445 Arrays are sets of zero or more elements of the same type, while
446 structures are a set of a fixed number of elements, each of any
447 type. Maps or dictionaries are implemented as arrays of a pair of
448 elements, so there can be zero or more elements in one map.
449
450 \section1 Extending the Type System
451
452 In order to use one's own type with QtDBus, the type has to be
453 declared as a Qt meta-type with the Q_DECLARE_METATYPE() macro and
454 registered with the qDBusRegisterMetaType() function. The
455 streaming operators \c{operator>>} and \c{operator<<} will be
456 automatically found by the registration system.
457
458 QtDBus provides template specializations for arrays and maps for
459 use with Qt's \l{Container classes}{container classes}, such as
460 QMap and QList, so it is not necessary to write the streaming
461 operator functions for those. For other types, and specially for
462 types implementing structures, the operators have to be explicitly
463 implemented.
464
465 See the documentation for QDBusArgument for examples for
466 structures, arrays and maps.
467
468 \section1 The Type System in Use
469
470 All of the QtDBus types (primitives and user-defined alike) can be
471 used to send and receive messages of all types over the bus.
472
473 \warning You may not use any type that is not on the list above,
474 including \a typedefs to the types listed. This also includes
475 QList<QVariant> and QMap<QString,QVariant>.
476*/
477
478/*!
479 \macro Q_NOREPLY
480 \relates QDBusAbstractAdaptor
481 \since 4.2
482
483 The Q_NOREPLY macro can be used to mark a method to be called and not wait for it to finish
484 processing before returning from QDBusInterface::call(). The called method cannot return any
485 output arguments and, if it does, any such arguments will be discarded.
486
487 You can use this macro in your own adaptors by placing it before your method's return value
488 (which must be "void") in the class declaration, as shown in the example:
489 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 12
490
491 Its presence in the method implementation (outside the class declaration) is optional.
492
493 \sa {Using QtDBus Adaptors}
494*/
Note: See TracBrowser for help on using the repository browser.