1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
5 \page usingadaptors.html
6 \title Using Qt D-Bus Adaptors
7 \brief How to create and use DBus adaptors in Qt.
9 \ingroup best-practices
11 Adaptors are special classes that are attached to any QObject-derived class
12 and provide the interface to the external world using D-Bus. Adaptors are
13 intended to be lightweight classes whose main purpose is to relay calls to
14 and from the real object, possibly validating or converting the input from
15 the external world and, thus, protecting the real object.
17 Unlike multiple inheritance, adaptors can be added at any time to any object
18 (but not removed), which allows for greater flexibility when exporting
19 existing classes. Another advantage of adaptors is to provide similar but not
20 identical functionality in methods of the same name in different interfaces,
21 a case which can be quite common when adding a new version of a standard
22 interface to an object.
24 In order to use an adaptor, one must create a class which inherits
25 QDBusAbstractAdaptor. Since that is a standard QObject-derived class, the
26 Q_OBJECT macro must appear in the declaration and the source file must be
27 processed with the \l {moc} tool. The class must also contain one
28 Q_CLASSINFO entry with the \c {"D-Bus Interface"} name, declaring which
29 interface it is exporting. Only one entry per class is supported.
31 Any public slot in the class will be accessible through the bus over messages
32 of the MethodCall type. (See \l {Declaring Slots in D-Bus Adaptors} for more
33 information). Signals in the class will be automatically relayed over D-Bus.
34 However, not all types are allowed signals or slots' parameter lists: see
35 \l {The Qt D-Bus Type System} for more information.
37 Also, any property declared with Q_PROPERTY will be automatically exposed
38 over the Properties interface on D-Bus. Since the QObject property system
39 does not allow for non-readable properties, it is not possible to declare
40 write-only properties using adaptors.
44 \li \l{Declaring Slots in D-Bus Adaptors}
45 \li \l{Declaring Signals in D-Bus Adaptors}
46 \li \l{The Qt D-Bus Type System}
47 \li In the \l{D-Bus Complex Ping Pong} example, \c complexpong.h and
48 \c complexpong.cpp show an implementation of QDBusAbstractAdaptor.
51 \sa QDBusAbstractAdaptor
55 \page qdbusdeclaringslots.html
56 \title Declaring Slots in D-Bus Adaptors
58 \nextpage Declaring Signals in D-Bus Adaptors
60 Slots in D-Bus adaptors are declared just like normal, public slots, but their
61 parameters must follow certain rules (see \l{The Qt D-Bus Type System} for more
62 information). Slots whose parameters do not follow those rules or that are not
63 public will not be accessible via D-Bus.
65 Slots can have one parameter of type \c{const QDBusMessage &}, which must
66 appear at the end of the input parameter list, before any output parameters.
67 This parameter, if present, will be initialized with a copy of the
68 current message being processed, which allows the callee to obtain
69 information about the caller, such as its connection name.
71 Slots can be of three kinds:
78 \section1 Asynchronous Slots
79 Asynchronous slots are those that do not normally return any reply to the
80 caller. For that reason, they cannot take any output parameters. In most
81 cases, by the time the first line of the slot is run, the caller function
82 has already resumed working.
84 However, slots must not rely on that behavior. Scheduling and message-dispatching
85 issues could change the order in which the slot is run. Code intending to
86 synchronize with the caller should provide its own method of synchronization.
88 Asynchronous slots are marked by the keyword \l Q_NOREPLY in the method
89 signature, before the \c void return type and the slot name. The \c quit()
90 slot in the \l {D-Bus Complex Ping Pong} example is an example of this.
92 \section1 Input-Only Slots
94 Input-only slots are normal slots that take parameters passed by value or
95 by constant reference. However, unlike asynchronous slots, the caller is
96 usually waiting for completion of the callee before resuming operation.
97 Therefore, non-asynchronous slots should not block or should state it its
98 documentation that they may do so.
100 Input-only slots have no special marking in their signature, except that
101 they take only parameters passed by value or by constant reference.
102 Optionally, slots can take a QDBusMessage parameter as a last parameter,
103 which can be used to perform additional analysis of the method call message.
105 \section1 Input and Output Slots
107 Like input-only slots, input-and-output slots are those that the caller is
108 waiting for a reply. Unlike input-only ones, though, this reply will contain
109 data. Slots that output data may contain non-constant references and may
110 return a value as well. However, the output parameters must all appear at
111 the end of the argument list and may not have input arguments interleaved.
112 Optionally, a QDBusMessage argument may appear between the input and the
115 \section1 Automatic Replies
117 Method replies are generated automatically with the contents of the output
118 parameters (if there were any) by the Qt D-Bus implementation. Slots need not
119 worry about constructing proper QDBusMessage objects and sending them over
122 However, the possibility of doing so remains there. Should the slot find out
123 it needs to send a special reply or even an error, it can do so by using
124 QDBusMessage::createReply() or QDBusMessage::createErrorReply() on the
125 QDBusMessage parameter and send it with QDBusConnection::send(). The
126 Qt D-Bus implementation will not generate any reply if the slot did so.
128 \warning When a caller places a method call and waits for a reply, it will
129 only wait for a limited amount of time. Slots intending to take a long time
130 to complete should make that fact clear in documentation so that callers
131 properly set higher timeouts.
133 \section1 Delayed Replies
135 In some circumstances, the called slot may not be able to process
136 the request immediately. This is frequently the case when the
137 request involves an I/O or networking operation which may block.
139 If this is the case, the slot should return control to the
140 application's main loop to avoid freezing the user interface, and
141 resume the process later. To accomplish this, it should make use
142 of the extra \c QDBusMessage parameter at the end of the input
143 parameter list and request a delayed reply.
145 We do this by writing a slot that stores the request data in a
146 persistent structure, indicating to the caller using
147 \l{QDBusMessage::setDelayedReply()}{QDBusMessage::setDelayedReply(true)}
148 that the response will be sent later.
150 \snippet code/doc_src_qdbusadaptors.cpp 10
152 In this case, the return value is unimportant; we return an arbitrary value
153 to satisfy the compiler.
155 When the request is processed and a reply is available, it should be sent
156 using the \c QDBusMessage object that was obtained. In our example, the
157 reply code could be something as follows:
159 \snippet code/doc_src_qdbusadaptors.cpp 11
161 As can be seen in the example, when a delayed reply is in place,
162 the return value(s) from the slot will be ignored by Qt D-Bus. They
163 are used only to determine the slot's signature when communicating
164 the adaptor's description to remote applications, or in case the
165 code in the slot decides not to use a delayed reply.
167 The delayed reply itself is requested from Qt D-Bus by calling
168 QDBusMessage::reply() on the original message. It then becomes the
169 responsibility of the called code to eventually send a reply to the
172 \warning When a caller places a method call and waits for a reply, it will
173 only wait for a limited amount of time. Slots intending to take a long time
174 to complete should make that fact clear in documentation so that callers
175 properly set higher timeouts.
177 \sa {Using Qt D-Bus Adaptors}, {Declaring Signals in D-Bus Adaptors},
178 {The Qt D-Bus Type System}, QDBusConnection, QDBusMessage
182 \page qdbusdeclaringsignals.html
183 \title Declaring Signals in D-Bus Adaptors
185 \previouspage Declaring Slots in D-Bus Adaptors
186 \nextpage The Qt D-Bus Type System
188 Any signal in a class derived from QDBusAbstractAdaptor will be automatically
189 relayed into D-Bus, provided that the signal's parameters conform to certain
190 rules (see \l{The Qt D-Bus Type System} for more information). No special code
191 is necessary to make this relay.
193 However, signals must still be emitted. The easiest way to emit an adaptor
194 signal is to connect another signal to it, so that Qt's signals and slots
195 mechanism automatically emits the adaptor signal, too. This can be done in
196 the adaptor's constructor, as you can see in the \l {D-Bus Complex Ping Pong}
199 The QDBusAbstractAdaptor::setAutoRelaySignals() convenience function can also
200 be used to make and break connections between signals in the real object and
201 the corresponding signals in the adaptor. It will inspect the list of signals
202 in both classes and connect those whose parameters match exactly.
204 \sa {Using Qt D-Bus Adaptors},
205 {Declaring Slots in D-Bus Adaptors},
206 {The Qt D-Bus Type System}, QDBusAbstractAdaptor
210 \page qdbustypesystem.html
211 \title The Qt D-Bus Type System
213 \previouspage Declaring Signals in D-Bus Adaptors
215 D-Bus has an extensible type system based on a few primitives and
216 composition of the primitives in arrays and structures. Qt D-Bus
217 implements the interface to that type system through the
218 QDBusArgument class, allowing user programs to send and receive
219 practically every C++ type over the bus.
221 \section1 Primitive Types
223 The primitive types are supported natively by QDBusArgument and
224 need no special customization to be sent or received. They are
225 listed below, along with the C++ class they relate to:
230 \li D-Bus equivalent type
272 Aside from the primitive types, QDBusArgument also supports two
273 non-primitive types natively, due to their widespread use in Qt
274 applications: QStringList and QByteArray.
276 \section1 Compound Types
278 D-Bus specifies three types of aggregations of primitive types
279 that allow one to create compound types. They are \c ARRAY, \c
280 STRUCT and maps/dictionaries.
282 Arrays are sets of zero or more elements of the same type, while
283 structures are a set of a fixed number of elements, each of any
284 type. Maps or dictionaries are implemented as arrays of a pair of
285 elements, so there can be zero or more elements in one map.
287 \section1 Extending the Type System
289 In order to use one's own type with Qt D-Bus, the type has to be
290 declared as a Qt meta-type with the Q_DECLARE_METATYPE() macro and
291 registered with the qDBusRegisterMetaType() function. The
292 streaming operators \c{operator>>} and \c{operator<<} will be
293 automatically found by the registration system.
295 Qt D-Bus provides template specializations for arrays and maps for
296 use with Qt's \l{Container classes}{container classes}, such as
297 QMap and QList, so it is not necessary to write the streaming
298 operator functions for those. For other types, and specially for
299 types implementing structures, the operators have to be explicitly
302 See the documentation for QDBusArgument for examples for
303 structures, arrays and maps.
305 \section1 The Type System in Use
307 All of the Qt D-Bus types (primitives and user-defined alike) can be
308 used to send and receive messages of all types over the bus.
310 \warning You may not use any type that is not on the list above,
311 including \a typedefs to the types listed. This also includes
312 QList<QVariant> and QMap<QString,QVariant>.
317 \relates QDBusAbstractAdaptor
320 The Q_NOREPLY macro can be used to mark a method to be called and not wait for it to finish
321 processing before returning from QDBusInterface::call(). The called method cannot return any
322 output arguments and, if it does, any such arguments will be discarded.
324 You can use this macro in your own adaptors by placing it before your method's return value
325 (which must be "void") in the class declaration, as shown in the example:
326 \snippet code/doc_src_qdbusadaptors.cpp 12
328 Its presence in the method implementation (outside the class declaration) is optional.
330 \sa {Using Qt D-Bus Adaptors}