Defining Enum custom types for Qt D-Bus introspect

2020-07-22 09:32发布

问题:

I am working with QDBUS which has the custom type as Enum. After googling I found below link which explains marshalling of QDBUS custom types.

http://techbase.kde.org/Development/Tutorials/D-Bus/CustomTypes#Adventurous_serialization_of_enumerations

This doesnot explain the annotation to be specified in the QTDBUS interospection xml to generate proxy using qdbusxml2cpp.

How to add Enum annotations in QTDBUS interospection xml?

Please if possible explain with some sample code.

回答1:

I found a solution for my problem:

First create a new header file called enums.h which looks like:

#ifndef ENUMS_H
#define ENUMS_H

#include <QtDBus>
#include "enumDBus.h"

enum Color {
    RED = 0,
    BLUE,
    GREEN
};

Q_DECLARE_METATYPE(Color)

#endif  /* ENUMS_H */

Note following line #include "enumDBus.h", you can find this header file here!

So after you declared the enum you can declare a method which takes the enum as argument, in this example I declared following method in calculator.h:

void setColor(Color color);

The implementation for this method:

void Calculator::setColor(Color c)
{
    switch (c) {
    case BLUE: std::cout << "Color: blue" << std::endl;
        break;
    case GREEN: std::cout << "Color: green" << std::endl;
        break;
    case RED: std::cout << "Color: reed" << std::endl;
        break;
    default:
        std::cout << "Color: FAIL!" << std::endl;
    }
}

Now let's generate the Interface description (xml), use following command

qdbuscpp2xml -M -s calculator.h -o com.meJ.system.CalculatorInterface.xml

The generation of method which contains custom types doesn't work properply, so we need to do some adjustments:

<!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.meJ.system.CalculatorInterface">
    <method name="setColor">
        <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="Color"/>
        <arg type="(i)" direction="in" name="c"/>
    </method>
  </interface>
</node>

With this xml file we can simply create our adaptors and interfaces classes.

In our main.cpp (on client and server!) we have to register our custom type:

int main(int argc, char** argv)
{
    qRegisterMetaType<Color>("Color");
    qDBusRegisterMetaType<Color>();
}

Client Side

Include generated calculatorInterface.h and enums.h in your main.cpp.

Now you can simply call your method:

int main(int argc, char** argv)
{
    qRegisterMetaType<Color>("Color");
    qDBusRegisterMetaType<Color>();

    QDBusConnection dbus = QDBusConnection::sessionBus();

    com::meJ::system::CalculatorInterface *calculator = new com::meJ::system::CalculatorInterface("com.meJ.system", "/Calc", dbus);
    if (calculator->isValid() == false) {
        cerr << "ERROR: " << qPrintable(calculator->lastError().message()) << endl;
        exit(1);
    }

    Color c = GREEN;
    calculator->setColor(c);
    std::cout << qPrintable(calculator->lastError().message()) << std::endl;

    exit(0);
}

If everything worked you should see following output at your server programm:

~# Color: green


标签: dbus qdbus