Hello Qt -- QtDBus quick start

Posted by OpSiS on Sun, 06 Mar 2022 17:18:14 +0100

1, Introduction to QtDBus

QtDBus is a Unix only library that uses D-Bus protocol for inter process communication. It is the encapsulation and implementation of the underlying API of D-Bus.

QtDBus module provides an interface extended by Qt signal slot mechanism. To use the QtDBus module, you need to add the following code to the code:

#include <QtDBus>

If you use qmake to build a program, you need to add the following code to the project file to link the QtDBus Library:

QT += qdbus

2, QtDBus type system

1. Introduction to QtDBus type system

D-Bus has an extended type system based on a composite of several native types and native types in arrays and structures. QtDBus module implements the type system through QDBusArgument class, allowing users to send and receive each C + + type through the bus.

2. Native type

QtDBus supports native types through QDBusArgument without special customization.

Qt type D-Bus type

uchar               BYTE

bool                BOOLEAN

short               INT16

ushort              UINT16

int                 INT32

uint                UINT32

qlonglong           INT64

qulonglong          UINT64

double              DOUBLE

QString             STRING

QDBusVariant        VARIANT

QDBusObjectPath     OBJECT_PATH

QDBusSignature      SIGNATURE

In addition to native types, QDBusArgument also supports two non-native types widely used in Qt applications, QStringList and QByteArray.

3. Composite type

D-Bus specifies three composite types aggregated from native types: ARRAY, STRUCT, and maps/dictionaries. ARRAY is a collection of zero or more identical elements. STRUCT is a collection composed of a fixed number of elements of different types. Maps or dictionaries is an ARRAY of element pairs. A map can have zero or more elements.

4. Extended type system

In order to use custom types in QtDBus modules, custom classes must use Q_DECLARE_METATYPE() is declared as a Qt meta type and registered with the qDBusRegisterMetaType() function. The stream operator will be found automatically by the registration system.

QtDBus module provides template specialization for Qt container classes to use arrays and maps, such as QMap and QList, without implementing stream operator functions. For other types, the flow operator must display the implementation.

5. Type system usage

All types defined by QtDBus can be used to send and receive messages through the bus. You cannot use any type other than the above types, including list types defined by typedefs, such as qlist < qvariant > and qmap < qstring, qvariant >.

3, QtDBus common classes

1,QDBusMessage

The QDBusMessage class represents a message sent or received by the D-Bus.

QDBusMessage object represents one of the four message types on the bus. The four message types are as follows:

A,Method calls

B,Method return values

C,Signal emissions

D,Error codes

Messages can be created using static functions createError(), createMethodCall(), createSignal(). Send a message using the QDBusConnection::send function.

2,QDBusConnection

QDBusConnection represents a connection to the D-Bus and is the starting point of a D-Bus session. Connecting objects through QDBusConnection can access remote objects and interfaces, connect remote signals to local slot functions, register objects, etc.

The D-Bus connection is created through the connectToBus() function, which will create a connection to the bus server, complete the initialization, and associate a connection name to the connection.

Use the disconnectFromBus() function to disconnect. Once the connection is disconnected, the call connectToBus() function will not rebuild the connection, and a new QDBusConnection instance must be created.

As an aid to the two most commonly used bus types, sessionBus() and systemBus() functions create and return the connection to the session bus and system bus respectively, which will be opened when it is first used and disconnected when the QCoreApplication destructor is called.

D-Bus supports point-to-point communication without using bus services. Two applications can communicate and exchange messages directly. You can do this by passing an address to the connectToBus() function.

QDBusConnection connectToBus(BusType type, const QString & name)

Open a connection of type, associate name with the connection name, and return the QDBusConnection object associated with this connection.

QDBusConnection connectToBus(const QString & address, const QString & name)

Open a private bus with address, associate name with connection name, and return the QDBusConnection object associated with this connection.

QDBusConnection connectToPeer(const QString & address, const QString & name)

Open a point-to-point connection to the address address, associate the name connection name, and return the QDBusConnection object associated with this connection.

void disconnectFromBus(const QString & name)

Close the bus connection named name

void disconnectFromPeer(const QString & name)

Close the peer connection named name

QByteArray localMachineId()

Returns a local ID known to the D-Bus system

QDBusConnection sender()

Returns the connection that sent the signal

QDBusConnection sessionBus()

Returns a QDBusConnection object opened to the session bus

QDBusConnection systemBus()

Returns a QDBusConnection object opened to the system bus

QDBusPendingCall asyncCall(const QDBusMessage & message, int timeout = -1)const

Send a message to the connection and return immediately. This function only supports method calls. Returns a QDBusPendingCall object used to track responses.

QDBusMessage call(const QDBusMessage & message, QDBus::CallMode mode = QDBus::Block, 
            int timeout = -1 ) const

The message is sent through this connection, blocked and waiting for a reply.

bool registerObject(const QString & path, QObject * object, 
                    RegisterOptions options = ExportAdaptors)

Register the object object to the path. The options option specifies how many objects will be exposed to the D-Bus. If the registration is successful, it returns true.

bool registerService(const QString & serviceName)

Attempt to register the serviceName service on the D-Bus. If the registration is successful, return true; If the name has been registered in other applications, the registration fails.

3,QDBusInterface

QDBusInterface is a proxy for the remote object interface.

QDBusInterface is a general accessor class, which is used to call remote objects, connect to the signal exported by remote objects, and obtain / set the value of remote properties. The QDBusInterface class is very useful for dynamic access to remote objects when the generated code representing the remote interface is not generated.

The call is usually realized by using the call () function. The call function constructs the message, sends the message through the bus, waits for the response and decodes the response. Signals are connected using the QObject::connect function. Finally, use QObject::property and QObject::setProperty functions to access properties.

4,QDBusReply

The QDBusReply class is used to store responses to method calls to remote objects.

A QDBusReply object is a subset of the response QDBusMessage object of the method call. The QDBusReply object contains only the first output parameter or error code and is used by the QDBusInterface derived class to allow the error code to be returned as the return parameter of the function.

QDBusReply<QString> reply = interface->call("RemoteMethod");
 if (reply.isValid())
     // use the returned value
     useValue(reply.value());
 else
     // call failed. Show an error condition.
     showError(reply.error());

For remote calls without output parameters or return values, use the isValid() function to test whether the response is successful.

5,QDBusAbstractAdaptor

The qdbusabstractadapter class uses the D-Bus adapter base class.

The qdbusabstractadapter class is the starting point for all objects that use D-Bus to provide interfaces to the outside world. You can use QDBusConnection::registerObject to register a QObject object by attaching one or more classes derived from qdbusabstractadapter to a common QObject object. Qdbusabstractadapter is a lightweight package, which is mainly used to relay the actual object and its signal.

Each qdbusabstractadapter derived class should use Q in the class definition_ ClassInfo macro to define the D-Bus interface. Note that only one interface can be exposed in this way.

Qdbusabstractadapter uses the standard QObject mechanism of signals, slots and attributes to determine which signals, slots and attributes are exposed to the bus. The signal sent by any qdbusabstractadapter derived class is automatically relayed to the registered object through any D-Bus connection.

Qdbusabstractadapter derived class objects must be created on the heap using new and need not be deleted by the user.

6,QDBusAbstractInterface

QDBusAbstractInterface is the base class of all D-Bus interfaces in QtDBus module that allow access to remote interfaces.

The automatically generated code class also inherits from QDBusAbstractInterface, and all methods described in this description are also valid in the generated code. In addition to the description here, the generated code class provides member functions for remote methods, allowing correct parameters and return values to be checked at compile time, as well as matching attribute types and matching signal parameters.

QDBusPendingCall asyncCall(const QString & method, 
                           const QVariant & arg1 = QVariant(), 
                           const QVariant & arg2 = QVariant(), 
                           const QVariant & arg3 = QVariant(), 
                           const QVariant & arg4 = QVariant(),
                           const QVariant & arg5 = QVariant(), 
                           const QVariant & arg6 = QVariant(), 
                           const QVariant & arg7 = QVariant(), 
                           const QVariant & arg8 = QVariant())

Call the method method in this interface and pass parameters to the remote method.

The parameters to be called will be passed to the remote method through the D-Bus input parameters, and the returned QDBusPendingCall object is used to define the response information.

This function has a maximum of 8 parameters. If there are more than 8 parameters or a variable number of parameters are passed, use the asyncCallWithArgumentList function.

QString value = retrieveValue();
QDBusPendingCall pcall = interface->asyncCall(QLatin1String("Process"), value);

QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);

QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 this, SLOT(callFinishedSlot(QDBusPendingCallWatcher*)));

7,QDBusArgument

The QDBusArgument class is used to organize and distribute D-Bus parameters. QDBusArgument is used to send parameters to remote applications through D-Bus and receive returns.

QDBusArgument is the core class of QtDBus type system, which is used for parsing and native types. Composite types can be created by using one or more native types in arrays, dictionaries, or structures.

The following code shows a structure consisting of an integer and a string constructed using the QtDBus type system.

struct MyStructure
{
     int count;
     QString name;
};

Q_DECLARE_METATYPE(MyStructure)
// Marshall the MyStructure data into a D-Bus argument
QDBusArgument &operator<<(QDBusArgument &argument, const MyStructure &mystruct)
{
    argument.beginStructure();
    argument << mystruct.count << mystruct.name;
    argument.endStructure();
    return argument;
}

// Retrieve the MyStructure data from the D-Bus argument
const QDBusArgument &operator>>(const QDBusArgument &argument, MyStructure &mystruct)
{
    argument.beginStructure();
    argument >> mystruct.count >> mystruct.name;
    argument.endStructure();
    return argument;
}

Before QDBusArgument uses this structure, it must be registered using the qDBusRegisterMetaType() function. Therefore, the following code should be added to the program:

qDBusRegisterMetaType<MyStructure>();

Once registered, the type can be in outgoing method call (QDBusAbstractInterface::call()), signal emission from registered object or incoming call from remote application.

8,QDBusConnectionInterface

The QDBusConnectionInterface class provides access to D-Bus bus services.

The D-Bus server provides a special interface org freedesktop. DBUS, which allows the client to run and access some properties of the bus, such as the list of currently connected clients. The QDBusConnectionInterface class provides access to org freedesktop. Access to DBUS interface.

The most commonly used in this class is to use registerService() and unregisterService() to register and unregister service names on the bus.

The QDBusConnectionInterface class defines four signals that are sent when there is a change in service status on the bus.

void callWithCallbackFailed(const QDBusError & error, const QDBusMessage & call)
void serviceOwnerChanged(const QString & name, const QString & oldOwner, 
                    const QString & newOwner)
void serviceRegistered(const QString & serviceName)
void serviceUnregistered(const QString & serviceName)

9,QDBusVariant

The QDBusVariant class enables programmers to recognize Variant types provided by the D-Bus type system. A D-Bus function that uses integers, D-Bus Variant types, and strings as parameters can be called using the following parameter list.

QList<QVariant> arguments;

arguments << QVariant(42) << QVariant::fromValue(QDBusVariant(43)) 
                << QVariant("hello");

myDBusMessage.setArguments(arguments);

When the D-Bus function returns a D-Bus variant type, you can use the following method to obtain it:

// call a D-Bus function that returns a D-Bus variant
QVariant v = callMyDBusFunction();

// retrieve the D-Bus variant
QDBusVariant dbusVariant = qvariant_cast<QDBusVariant>(v);

// retrieve the actual value stored in the D-Bus variant
QVariant result = dbusVariant.variant();

QVariant in QDBusVariant needs to distinguish between a normal D-Bus value and a value in QDBusVariant.

4, QtDBus tool

1,qdbusviewer

Qdbusviewer is used to view services, objects, interfaces and methods of interfaces on the D-Bus. The use method is executed directly on the command line: qdbusviewer

 2,qdbuscpp2xml

qdbuscpp2xml will parse the C + + header files or source files of QObject derived classes and generate introspective XML files of D-Bus. qdbuscpp2xml will distinguish the input and output of the function. If the parameter is declared const, it will be the input, otherwise it may be regarded as the output.

The syntax of qdbuscpp2xml is as follows:

qdbuscpp2xml [options...] [files...]

The Options parameters are as follows:

-p|-s|-m: only scripted attributes, signals and methods (slot functions) are parsed

-P|-S|-M: analyze all attributes, signals and methods (slot function)

-a: Output all scripted content, equivalent to - psm

-A: Output all contents, equivalent to - PSM

-O < filename >: output content to filename file

Parse all methods and output to com scorpio. test. The XML file command is as follows:

qdbuscpp2xml -M test.h -o com.scorpio.test.xml
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">

<node>

  <interface name="com.scorpio.test.value">
    <method name="maxValue">
      <arg type="i" direction="out"/>
    </method>

    <method name="minValue">
      <arg type="i" direction="out"/>
    </method>

    <method name="value">
      <arg type="i" direction="out"/>
    </method>

    <method name="setValue">
      <arg name="value" type="i" direction="in"/>
    </method>

  </interface>

</node>

3,qdbusxml2cpp

qdbusxml2cpp generates C + + implementation code according to the interface defined in the input file.

qdbusxml2cpp can help to automatically generate the implementation code inherited from qdbusabstractadapter and QDBusAbstractInterface for process communication server and client, which simplifies the code design of developers.

The syntax of qdbusxml2cpp is as follows:

qdbusxml2cpp [options...] [xml-or-xml-file] [interfaces...]

The Options parameters are as follows:

-A < filename >: output adapter code to filename

-C < classname >: use classname as the class name of the generated class

-I < filename >: add #include to output

-L < classname >: when generating adapter code, use classname as the parent class

-m: Include #include "filename.moc" statement in cpp file

-N: Do not use namespaces

-P < filename >: generate Proxy code to filename file

Parse com scorpio. test. XML file, generate the adapter class valueadapter, and the file name is valueadapter h,value Adaptor. The CPP command line is as follows:

qdbusxml2cpp com.scorpio.test.xml -i test.h -a valueAdaptor

Parse com scorpio. test. XML file to generate the Proxy class ComScorpioTestValueInterface. The file name is testinterface h,testInterface. The CPP command line is as follows:

qdbusxml2cpp com.scorpio.test.xml -p testInterface

5, QtDBus programming

1. Create and register service objects

test.h documents:

#ifndef TEST_H
#define TEST_H

#include <QObject>

class test: public QObject
{
    Q_OBJECT
    //Define the Interface name as com scorpio. test. value
    Q_CLASSINFO("D-Bus Interface", "com.scorpio.test.value")
public:
    test(int value);
public slots:
    int maxValue();
    int minValue();
    int value();
private:
    int m_value;
};

#endif // TEST_H

test.cpp file:

#include "test.h"

test::test(int value)
{
    m_value = value;
}

int test::maxValue()
{
    return 100;
}

int test::minValue()
{
    return 0;
}

int test::value()
{
    return m_value;
}

main.cpp file:

#include <QCoreApplication>
#include <QDBusConnection>
#include <QDebug>
#include <QDBusError>

#include "test.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    //Establish connection to session bus
    QDBusConnection connection = QDBusConnection::sessionBus();
    //Register on session # bus as com scorpio. Test services
    if(!connection.registerService("com.scorpio.test"))
    {
        qDebug() << "error:" << connection.lastError().message();
        exit(-1);
    }

    test object(60);
    //Register the object named / test/objects and export all slot functions of class object as the method of object
    connection.registerObject("/test/objects", 
                &object,QDBusConnection::ExportAllSlots);

    return a.exec();
}

After starting the program, open qdbusviewer on the command line to view the session bus.

Double click the Method method to call it.

2. Access Service through QDBusMessage

Make sure com scorpio. The test service runs on the bus.

Write a console program and use messages to visit com scorpio. Test service.

#include <QCoreApplication>
#include <QDBusMessage>
#include <QDBusConnection>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //Construct a method_call message, service name: com scorpio. Test, the object path is: / test/objects
    //The interface name is com scorpio. test. Value, method name is value
    QDBusMessage message = QDBusMessage::createMethodCall("com.scorpio.test",
                           "/test/objects",
                           "com.scorpio.test.value",
                           "value");

    //send message
    QDBusMessage response = QDBusConnection::sessionBus().call(message);
    //Judge whether the method is returned correctly
    if (response.type() == QDBusMessage::ReplyMessage)
    {
        //Get the return value from the return parameter
        int value = response.arguments().takeFirst().toInt();
        qDebug() << QString("value =  %1").arg(value);
    }
    else
    {
        qDebug() << "value method called failed!";
    }

    return a.exec();
}

3. Access Service via QDBusInterface #

Write a console program and use the interface to access com scorpio. Test service.

#include <QCoreApplication>
#include <QDBusMessage>
#include <QDBusConnection>
#include <QDBusReply>
#include <QDBusInterface>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //Create QDBusInterface interface
    QDBusInterface interface("com.scorpio.test", "/test/objects",
                             "com.scorpio.test.value",
                             QDBusConnection::sessionBus());

    if (!interface.isValid())
    {
        qDebug() << qPrintable(QDBusConnection::sessionBus().lastError().message());
        exit(1);
    }

    //Call the remote value method
    QDBusReply<int> reply = interface.call("value");
    if (reply.isValid())
    {
        int value = reply.value();
        qDebug() << QString("value =  %1").arg(value);
    }
    else
    {
        qDebug() << "value method called failed!";
    }

    return a.exec();
}

4. Automatically generate Proxy classes from D-Bus XML

Proxy Object provides a more intuitive way to access services, just like calling methods of local objects.  

The process of generating Proxy class is as follows:

A. Use the tool qdbuscpp2xml to retrieve data from object H generate XML file;

qdbuscpp2xml -M test.h -o com.scorpio.test.xml
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">

<node>
  <interface name="com.scorpio.test.value">
    <method name="maxValue">
      <arg type="i" direction="out"/>
    </method>

    <method name="minValue">
      <arg type="i" direction="out"/>
    </method>

    <method name="value">
      <arg type="i" direction="out"/>
    </method>

  </interface>

</node>

B. Use the tool qdbusxml2cpp to generate classes inherited from QDBusInterface from XML files

qdbusxml2cpp com.scorpio.test.xml -p valueInterface

Generate two files: valueinterface CPP and valueinterface h

valueInterface.h documents:

/*
 * This file was generated by qdbusxml2cpp version 0.7
 * Command line was: qdbusxml2cpp com.scorpio.test.xml -p testInterface
 *
 * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
 *
 * This is an auto-generated file.
 * Do not edit! All changes made to it will be lost.
 */

#ifndef TESTINTERFACE_H_1526737677
#define TESTINTERFACE_H_1526737677

#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>

/*
 * Proxy class for interface com.scorpio.test.value
 */
class ComScorpioTestValueInterface: public QDBusAbstractInterface
{
    Q_OBJECT
public:
    static inline const char *staticInterfaceName()
    { return "com.scorpio.test.value"; }

public:
    ComScorpioTestValueInterface(const QString &service, const QString &path, 
                const QDBusConnection &connection, QObject *parent = 0);

    ~ComScorpioTestValueInterface();
public Q_SLOTS: // METHODS
    inline QDBusPendingReply<int> maxValue()
    {
        QList<QVariant> argumentList;
        return asyncCallWithArgumentList(QLatin1String("maxValue"), argumentList);
    }
    inline QDBusPendingReply<int> minValue()
    {
        QList<QVariant> argumentList;
        return asyncCallWithArgumentList(QLatin1String("minValue"), argumentList);
    }

    inline QDBusPendingReply<int> value()
    {
        QList<QVariant> argumentList;
        return asyncCallWithArgumentList(QLatin1String("value"), argumentList);
    }

Q_SIGNALS: // SIGNALS
};



namespace com {
  namespace scorpio {
    namespace test {
      typedef ::ComScorpioTestValueInterface value;
    }
  }
}

#endif

valueInterface.cpp file:

/*
 * This file was generated by qdbusxml2cpp version 0.7
 * Command line was: qdbusxml2cpp com.scorpio.test.xml -p testInterface
 *
 * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
 *
 * This is an auto-generated file.
 * This file may have been hand-edited. Look for HAND-EDIT comments
 * before re-generating it.
 */

#include "testInterface.h"

/*
 * Implementation of interface class ComScorpioTestValueInterface
 */

ComScorpioTestValueInterface::ComScorpioTestValueInterface(const QString &service, 
        const QString &path, const QDBusConnection &connection, QObject *parent): 
    QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
{

}

ComScorpioTestValueInterface::~ComScorpioTestValueInterface()
{

}

Call Proxy class to access Service as follows:

#include <QCoreApplication>
#include <QDBusMessage>
#include <QDBusConnection>
#include <QDBusReply>
#include <QDBusInterface>
#include <QDebug>
#include "testInterface.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //Initialize the automatically generated Proxy class com::scorpio::test::value
    com::scorpio::test::value test("com.scorpio.test",
                                   "/test/objects",
                                   QDBusConnection::sessionBus());

    //Call the value method
    QDBusPendingReply<int> reply = test.value();
    //The Proxy class generated by qdbusxml2cpp passes messages asynchronously,
    //Therefore, you need to call waitForFinished to wait until the Message execution is completed
    reply.waitForFinished();
    if (reply.isValid())
    {
        int value = reply.value();
        qDebug() << QString("value =  %1").arg(value);
    }
    else
    {
        qDebug() << "value method called failed!";
    }

    return a.exec();
}

5. Registering objects with adapters

You can directly register the test class as an Object on the message bus, but QT4 does not recommend it. QT4 recommends using an Adapter to register objects.

In most cases, you may only need to selectively publish the methods in the custom class to the message bus. Using the Adapter can easily realize selective publishing.

The process of generating Adapter class is as follows:

A. Use the tool {qdbuscpp2xml to get the data from test H generate XML file

qdbuscpp2xml -M test.h -o com.scorpio.test.xml 

B. Edit com scorpio. test. XML, select the method to be published, and delete the method that does not need to be published.

C. Use the tool qdbusxml2cpp to generate classes inherited from QDBusInterface from XML files

qdbusxml2cpp com.scorpio.test.xml -i test.h -a valueAdaptor

Generate two files: valueadapter CPP and valueadapter h

valueAdaptor.h documents:

/*
 * This file was generated by qdbusxml2cpp version 0.7
 * Command line was: qdbusxml2cpp com.scorpio.test.xml -i test.h -a valueAdaptor
 *
 * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
 *
 * This is an auto-generated file.
 * This file may have been hand-edited. Look for HAND-EDIT comments
 * before re-generating it.
 */

#ifndef VALUEADAPTOR_H_1526742670
#define VALUEADAPTOR_H_1526742670

#include <QtCore/QObject>
#include <QtDBus/QtDBus>
#include "test.h"
class QByteArray;
template<class T> class QList;
template<class Key, class Value> class QMap;
class QString;
class QStringList;
class QVariant;


/*
 * Adaptor class for interface com.scorpio.test.value
 */
class ValueAdaptor: public QDBusAbstractAdaptor
{
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface", "com.scorpio.test.value")
    Q_CLASSINFO("D-Bus Introspection", ""
"  <interface name=\"com.scorpio.test.value\">\n"
"    <method name=\"maxValue\">\n"
"      <arg direction=\"out\" type=\"i\"/>\n"
"    </method>\n"
"    <method name=\"minValue\">\n"
"      <arg direction=\"out\" type=\"i\"/>\n"
"    </method>\n"
"  </interface>\n"
        "")
public:
    ValueAdaptor(QObject *parent);
    virtual ~ValueAdaptor();

public: // PROPERTIES
public Q_SLOTS: // METHODS
    int maxValue();
    int minValue();
Q_SIGNALS: // SIGNALS

};


#endif

valueAdaptor.cpp file:

/*
 * This file was generated by qdbusxml2cpp version 0.7
 * Command line was: qdbusxml2cpp com.scorpio.test.xml -i test.h -a valueAdaptor
 *
 * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
 *
 * This is an auto-generated file.
 * Do not edit! All changes made to it will be lost.
 */

#include "valueAdaptor.h"
#include <QtCore/QMetaObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>

/*
 * Implementation of adaptor class ValueAdaptor
 */

ValueAdaptor::ValueAdaptor(QObject *parent)
    : QDBusAbstractAdaptor(parent)
{
    // constructor
    setAutoRelaySignals(true);
}

ValueAdaptor::~ValueAdaptor()
{
    // destructor
}

int ValueAdaptor::maxValue()
{
    // handle method call com.scorpio.test.value.maxValue
    int out0;
    QMetaObject::invokeMethod(parent(), "maxValue", Q_RETURN_ARG(int, out0));
    return out0;
}

int ValueAdaptor::minValue()
{
    // handle method call com.scorpio.test.value.minValue
    int out0;
    QMetaObject::invokeMethod(parent(), "minValue", Q_RETURN_ARG(int, out0));
    return out0;
}

Call the adapter class to register the Object object as follows:

#include <QCoreApplication>
#include <QDBusConnection>
#include <QDebug>
#include <QDBusError>
#include "test.h"
#include "valueAdaptor.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QDBusConnection connection = QDBusConnection::sessionBus();
    test object(60);
    //Valueadapter is the adapter class generated by qdbusxml2cpp
    ValueAdaptor valueAdaptor(&object);
    if (!connection.registerService("com.scorpio.test"))
    {
        qDebug() << connection.lastError().message();
        exit(1);
    }
    connection.registerObject("/test/objects", &object);
    return a.exec();
}

Use qdbusviewer to view the published method.

6. Automatically start the Service

D-Bus system provides a mechanism to automatically run the application when accessing a service.

You need to establish com.com under / usr/share/dbus-1/services scorpio. test. Service file. The contents of the file are as follows:

[D-BUS Service]

Name=com.scorpio.test

Exec=/path/to/scorpio/test

You don't have to run the application manually before accessing the method of test.

Topics: Qt