QT D-Bus 复杂参数(自定义)传递

网上一搜,关于D-Bus和QT的资料不少,但是绝大多数都对传递自定义数据类型这个问题闭口不谈。看来这个有必要写个文章记录一下。

首先要说的是,我这里不再介绍D-Bus和QDbus的基础知识,本文直击要点。另外本文参考了KDE的一些文档。

需求:使用标准的信号和槽,通过QDBus传递自定义的struct或者class数据类型。

首先,需要定义需要通过D-Bus传递的自定义数据类型,我们这里定义一个Message类型:
#include <QtDBus>
 
class Message
{
public:

构造函数等略

friend QDBusArgument &operator<<(QDBusArgument &argument, const Message &message);

friend const QDBusArgument &operator>>(const QDBusArgument &argument, Message &message);

static void registerMetaType();
 
private:
    QString m_strMessage;
};
 
Q_DECLARE_METATYPE(Message)

可以看到有几个比较特殊的地方:

首先我们重载了<<和>>两个运算符,这是将自定义数据类型融合到QT的类型系统所必需的:
QDBusArgument &operator<<(QDBusArgument &argument, const Message& message)
{

argument.beginStructure();

argument << message.m_strMessage;

argument.endStructure();

return argument;
}
 
const QDBusArgument &operator>>(const QDBusArgument &argument, Message &message)
{

argument.beginStructure();

argument >> message.m_strMessage;

argument.endStructure();

return argument;
}

其次,这个自定义数据类型需要注册到QT和D-Bus的类型系统:
void Message::registerMetaType()
{

qRegisterMetaType<Message>("Message");

qDBusRegisterMetaType<Message>();
}

XML中结构体中数据类型定义

a ARRAY 数组

b BOOLEAN 布尔值

d DOUBLE IEEE 754双精度浮点数

g SIGNATURE 类型签名

i INT32 32位有符号整数

n INT16 16位有符号整数

o OBJECT_PATH 对象路径

q UINT16 16位无符号整数

s STRING 零结尾的UTF-8字符串

t UINT64 64位无符号整数

u UINT32 32位无符号整数

v VARIANT 可以放任意数据类型的容器,数据中包含类型信息。例如glib中的GValue。

x INT64 64位有符号整数

y BYTE 8位无符号整数

() 定义结构时使用。例如"(i(ii))"

{} 定义键-值对时使用。例如"a{us}"

定义结构体需要在XML中声明

<annotation value="Message" name="org.qtproject.QtDBus.QtTypeName.In0"/>,其中In0表示第一个入参,根据实际情况定。样例:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="introspect.xsl"?>
<node xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="/org/alibaba/kenton" xsi:noNamespaceSchemaLocation="introspect.xsd">
  <interface name="org.alibaba.kenton.hello">
    <version>1.0.0</version>
    <doc>
      <line>This is a test interface</line>
    </doc>
    <method name="GetVersion">
      <doc>
        <line>GetVersion = This method returns the API version implemented by the server application</line>
      </doc>
	  <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="SVersion"/>
      <arg name="version" type="(qqqs)" direction="out">
        <doc>
          <line>version = struct(major,minor,micro,date)</line>
          <line>major = major</line>
          <line>minor = minor</line>
          <line>micro = micro</line>
          <line>date = release date</line>
        </doc>
      </arg>
    </method>
  </interface>
</node>

有了这个数据类型,就可以写描述D-Bus接口的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="demo.Action">
        <signal name="messageSent">

            <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="Message"/>
            <arg name="message" type="a(i)" direction="out"/>
        </signal>
        <method name="sendMessage">

            <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="Message"/>
            <arg name="message" type="a(i)" direction="in"/>
        </method>
    </interface>
</node>

这里有两个特殊点,一个是参数的数据类型,因为是我们自定义的,不存在于D-Bus规范中,所以参数的type在这里可以乱写。另一个就是,既然是自定义的,就要说明这个自定义的数据类型到底是啥(在这里是Message)。<annotation>在参数声明之前,即在<arg>前。

OK,有了上面这些啰嗦的准备工作,下面调用QT自带的D-Bus工具,就可以自动生成相关的接口和代理类了:

qdbusxml2cpp Chat.xml -i Message.h -a MessageAdaptor

qdbusxml2cpp Chat.xml -i Message.h -p MessageInterface

后续就是标准的调用QDBus过程了,本文不再废话,请参考其他入门资料。大体上就是这样:

接收:

connect(&m_MessageInterface, SIGNAL(messageSent(Message)), SLOT(onMessageSent(Message)));

发送:

Message message(…);

m_MessageInterface.sendMessage(message);

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值