QT中DBus的用法


目  录
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的守护进程上注册服务和注册对象。

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

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

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

例如:

<!--[if !supportLists]-->1)        <!--[endif]-->创建QT的DBus信号

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

<!--[if !supportLists]-->2)        <!--[endif]-->给信号赋值  

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

<!--[if !supportLists]-->3)        <!--[endif]-->发射信号

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

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

<!--[if !supportLists]-->1)        <!--[endif]-->绑定信号

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

<!--[if !supportLists]-->2)        <!--[endif]-->在槽中进行相关的处理

在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

<!--[if !supportLists]-->1)        <!--[endif]-->创建一个QDBusMessage的方法调用

<!--[if !supportLists]-->a)         <!--[endif]-->QDBusMessage m = QDBusMessage::createMethodCall("hotel.server",

<!--[if !supportLists]-->                                                                                                            i.              <!--[endif]-->"/hotel/path",

<!--[if !supportLists]-->                                                                                                          ii.              <!--[endif]-->"hotel.interface",

<!--[if !supportLists]-->                                                                                                        iii.              <!--[endif]-->"checkIn");

<!--[if !supportLists]-->2)        <!--[endif]-->给方法传递参数

<!--[if !supportLists]-->a)         <!--[endif]-->m<<this->ui->checkInlineEdit->text().toInt();

<!--[if !supportLists]-->3)        <!--[endif]-->调用方法

<!--[if !supportLists]-->a)         <!--[endif]-->QDBusMessage response = QDBusConnection::sessionBus().call(m);

<!--[if !supportLists]-->4)        <!--[endif]-->判断方法的返回值

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

<!--[if !supportLists]-->1)        <!--[endif]-->创建一个QDBusInterface的实例

QDBusInterface iface( "hotel.server",

"/hotel/path",

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

if (!iface.isValid()) {

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

exit(1);

}

<!--[if !supportLists]-->2)        <!--[endif]-->传递参数

int num_room;

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

 

<!--[if !supportLists]-->3)        <!--[endif]-->呼叫远程的checkIn,参数为num_room

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

<!--[if !supportLists]-->4)        <!--[endif]-->判断返回值

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");

}

  • 1
  • 2
  • 3
  • 下一页

相关内容