DBus-1-TQt  1.0
Using D-Bus as a client

Contents:

Introduction

While it is of course possible to just exchange D-Bus messages with a D-Bus service, it is a lot more comfortable to use TQT_DBusProxy.

With TQT_DBusProxy you only need to specify the service object once, i.e. its D-Bus name, path and interface, and just provide the method and its parameters when initiating an invokation.

Additionally the proxy transforms D-Bus signals from the proxy's peer (the D-Bus service object's interface it is associated with) to TQObject signal carrying the original signal's content.

A simple D-Bus client example

#include <dbus/tqdbusconnection.h>
#include <dbus/tqdbusmessage.h>
#include <dbus/tqdbusproxy.h>
int main()
{
// establish a connection to the session bus
if (!connection.isConnected())
tqFatal("Failed to connect to session bus");
// create a proxy object for method calls
TQT_DBusProxy proxy(connection);
proxy.setService("org.freedesktop.DBus"); // who we work with
proxy.setPath("/org/freedesktop/DBus"); // which object inside the peer work with
proxy.setInterface("org.freedesktop.DBus"); // which of its interfaces we will use
// call the "ListNames" method. It returns an array of string, in TQt3 terms
// a TQStringList, it expects no parameters
TQT_DBusMessage reply = proxy.sendWithReply("ListNames", params);
tqFatal("Call failed");
if (reply.count() != 1 || reply[0].type() != TQT_DBusData::List)
tqFatal("Unexpected reply");
bool ok = false;
TQStringList names = reply[0].toTQStringList(&ok);
if (!ok) tqFatal("Unexpected reply");
for (TQStringList::iterator it = names.begin(); it != names.end(); ++it)
{
tqDebug("%s", (*it).local8Bit().data());
}
return 0;
}
Provides access to a specific D-Bus bus.
static TQT_DBusConnection sessionBus()
Gets a connection to the session bus.
bool isConnected() const
Returns whether the connection is connected to a bus.
A message converts and transports data over D-Bus.
MessageType type() const
Returns which kind of message this is.
Client interface to a remote service object.
Definition: tqdbusproxy.h:238

Program initialization

A connection to the bus is acquired using TQT_DBusConnection::sessionBus()

Next, a proxy is created for the object "/org/freedesktop/DBus" with interface "org.freedesktop.DBus" on the service "org.freedesktop.DBus"

This is a proxy for the message bus itself.

Method invocation

There are two choices for method invocation:

  • sychronous (blocking) calls
  • asynchronous (non-blocking) calls

Synchronous method calls

As seen in the example code above, a synchronous method call can be achieved by TQT_DBusProxy::sendWithReply(). It sends a method call to the remote object, and blocks until reply is received. The outgoing arguments are specified as a list of TQT_DBusData.

Asynchronous method calls

To invoke a method asynchronously, connect the proxy's signal TQT_DBusProxy::asyncReply(int, const TQT_DBusMessage&) to a suitable slot like with any other TQt Signal-Slot connection.

Then call TQT_DBusProxy::sendWithAsyncReply() It returns a numerical identifier of the call, so it can be related in the slot once the result is available.

The slot's first argument is the reveived reply's call identifier as returned by the method call. The second parameter is the reply message similar to the one in the synchronous call.

Note
For asynchronous calls you'll need a running event loop, i.e. a TQApplication object and its exec() having been invoked.

Connecting to D-Bus signals

To receive D-BUS signals just connect to the TQT_DBusProxy's signal TQT_DBusProxy::dbusSignal(const TQT_DBusMessage&)

It will be emitted whenever a D-Bus signal message is received from the peer object. Filtering of signals is based on the value set for service, path and interface

Note
Filtering for service will only happen if service is a unique D-Bus name, i.e. if it starts with a colon ":" since D-Bus signals carry the sender's unique name and filtering by a requested name would reject all signals

Usually a proxy will be also be used to send to the peer object, thus having them all set. However if a proxy is only needed for signals, any of the three properties can be omitted (e.g. set to TQString() ), in which case only the available properties will be checked against the respective message field when deciding about dropping or emitting the message. See TQT_DBusProxy::handleDBusSignal()

If you want all signal travelling on the bus, or apply filtering for different criteria, e.g. get all signals coming from interfaces starting with "org.", use TQT_DBusConnection::connect() instead. The signature of the slot stays the same.

Signal example

First declare a receiver class:

class MyReceiver : public TQObject
{
Q_OBJECT
public slots:
void handleDBusSignal(const TQT_DBusMessage&);
};

Then somewhere else in a source file:

MyReceiver* receiver1 = new MyReceiver();
connection.connect(receiver1, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&)));
bool connect(TQObject *object, const char *slot)
Connects an object to receive D-Bus signals.

receiver1 will get all signals on this connection

TQT_DBusProxy* proxy = new TQT_DBusProxy(connection);
proxy->setService("org.freedesktop.DBus"); // who we work with
proxy->setPath("/org/freedesktop/DBus"); // which object inside the peer work with
proxy->setInterface("org.freedesktop.DBus"); // which of its interfaces we will use
MyReceiver* receiver2 = new MyReceiver();
TQObject::connect(proxy, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)),
receiver2, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&)));
void setService(const TQString &service)
Sets the peer's service name.
Definition: tqdbusproxy.cpp:98
void setInterface(const TQString &interface)
Sets the name of the peer interface.
void setPath(const TQString &path)
Sets the peer's object path.

receiver2 will only get signals coming from the proxy's peer interface