目  录

1 概述... 2

2 QT中Dbus的最简单的用法... 3

3 QT中DBus的常规用法... 4

3.1 客户端的用法1:使用QDBusMessage. 4

3.2客户端的用法2:使用DBusInterface. 4

3.3 客户端的用法3:使用DBusProxy. 5

3.4服务端的用法1:直接注册对象和服务... 6

3.5 服务端的用法2:使用DBusAdapter 6

4 QT中Dbus的特殊的用法(使用QT的信号) 7

1 概述

D-Bus是一种高级的进程间通信机制,它由freedesktop.org项目提供,使用GPL许可证发行。D-Bus最主要的用途是在Linux桌面环境为进程提供通信,同时能将Linux桌面环境和Linux内核事件作为消息传递到进程。D-Bus的主要概率为总线,注册后的进程可通过总线接收或传递消息,进程也可注册后等待内核事件响应,例如等待网络状态的转变或者计算机发出关机指令。目前,D-Bus已被大多数Linux发行版所采用,开发者可使用D-Bus实现各种复杂的进程间通信任务。

D-Bus是一个消息总线系统,其功能已涵盖进程间通信的所有需求,并具备一些特殊的用途。D-Bus是三层架构的进程间通信系统,其中包括:

接口层:接口层由函数库libdbus提供,进程可通过该库使用D-Bus的能力。

总线层:总线层实际上是由D-Bus总线守护进程提供的。它在Linux系统启动时运行,负责进程间的消息路由和传递,其中包括Linux内核和Linux桌面环境的消息传递。

包装层:包装层一系列基于特定应用程序框架的Wrapper库。

在QT中的Dbus是使用的Dbus的包装层libdbus-qt.

要查看Dbus总线上的服务和对象可以借助d-feet 和qdbusviewer

要发送信号可以使用dbus-send,要查看Dbus上的消息流可以使用dbus-monitor

QT Dbus是在QT4.2中才引进到QT中来的,还有很多的地方不是很完善,在网上DBus的资料比较多,不过很多都是基入GTK的,基入QT的资料还比较的少。

2 QT中Dbus的最简单的用法

关于QT中的DBus的用法介绍的文章比较的少,网上只有这篇文章(国外的网站上可能有更多,只是没有发现而已)和QT中的四个例子程序。

这个最简单的用法是在使用中发现的,不需要在Dbus的守护进程上注册服务和注册对象。

注册了对象后:对象中的导出的槽就可以供其他的客户端来调用了。

注册了服务后:对象就有了一个公共名,没有注册是只有三个唯一名。

在发送端只需创建一个信号原后发送即可,

例如:

1)        创建QT的DBus信号

QDBusMessage msg =QDBusMessage::createSignal("/hotel/path",  "hotel.interface", "checkIn");

2)        给信号赋值

msg<ui->checkInlineEdit->text().toInt();

3)        发射信号

QDBusConnection::sessionBus().send(msg);

在接受端同样只需要简单的两三步即可

1)        绑定信号

QDBusConnection::sessionBus().connect(QString(),QString(),"dbus.client. interface","Active",this,SLOT(ActiveEvent(int)));

2)        在槽中进行相关的处理

在ActiveEvent槽中执行你的应用程序需要对这个信号做出的反应即可。

这样的使用在DBUS的守护进程中没有服务,只有三个唯一名,没有公共名,也没有任何的信号、槽、属性。

可以通过d-feet、 qdbusviewe来查看。

可以通过dbus-monitor监视信号发送过程

可以参考示例DBusSignalMethod中DBusServerDBusSignal和DBusClientDBusSignal

3 QT中DBus的常规用法

在以下这篇文章中已经很好的介绍了QT DBus的各种常规的用法了,在此就重复了,这种用法主要是在服务端,需要在DBus的守护进程上注册对象和注册服务,原后其他的客户端就可以自由的调用了。

不过这种方式也有一个好处,调用是服务端的返回的参数就只发给调用的客户端,是一对一的,不想上面的用信号的方式,信号的方式,发送的信号是一对多的。

在也有几个小的例子程序是根据D-Bus和QT4 (wwang's blog一蓑烟雨任平生)的例子改编的。

在常规用法中也分客户端和服务端的,

客户端有三种用法,服务端有两个用法。

3.1 客户端的用法1:使用QDBusMessage

可以参考实例DBusMessage中的DBusServer和DBusClient

1)        创建一个QDBusMessage的方法调用

a)         QDBusMessage m = QDBusMessage::createMethodCall("hotel.server",

                                                                                                            i.              "/hotel/path",

                                                                                                          ii.              "hotel.interface",

                                                                                                        iii.              "checkIn");

2)        给方法传递参数

a)         m<ui->checkInlineEdit->text().toInt();

3)        调用方法

a)         QDBusMessage response = QDBusConnection::sessionBus().call(m);

4)        判断方法的返回值

if (response.type() == QDBusMessage::ReplyMessage) {

// QDBusMessage的arguments不仅可以用来存储发送的参数,也用来存储返回值;

// 这里取得checkIn的返回值

int num_room = response.arguments().takeFirst().toInt();

qDebug("Got %d %s\n", num_room, (num_room > 1) ? "rooms" : "room");

} else

{

qDebug( "Check In fail!\n");

}

3.2客户端的用法2:使用DBusInterface

可以参考实例DBusInterface中的DBusServer和DBusClientInterface

1)        创建一个QDBusInterface的实例

QDBusInterface iface( "hotel.server",

"/hotel/path",

"hotel.interface", QDBusConnection::sessionBus());

if (!iface.isValid()) {

qDebug() << qPrintable(QDBusConnection::sessionBus().lastError().message());

exit(1);

}

2)        传递参数

int num_room;

num_room= this->ui->checkInlineEdit->text().toInt();

3)        呼叫远程的checkIn,参数为num_room

QDBusReply reply = iface.call("checkIn", num_room);

4)        判断返回值

if (reply.isValid()) {

num_room = reply.value();

qDebug("Got %d %s\n", num_room, (num_room > 1) ? "rooms" : "room");

} else {

qDebug( "Check In fail!\n");

}0b1331709591d260c1c78e86d0c51c18.png

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐