自从Qt-4.2版本引入D-Bus作为进程通信的一个方法之后,它就越来越有取代qcop的趋势。它不仅在应用层之间可以互相通信,还可以和内核做通信。比如某些硬件事件的发生,就可以通过D-Bus来交互。Linux系统中的蓝牙bluez正是使用了这种D-Bus.
那我们就来看看在我们的Qt应用中怎么使用QtDBus功能。
作为服务器端,我们需要做的工作有:
1. 申请一个总线连接
2. 在总线连接上挂载服务,这样其他进程才能请求该服务
3. 在挂载的服务上注册一个执行服务的对象
作为服务请求端,我们需要做的工作有:
a. 申请一个总线连接
b. 创建一个接口,连接到要请求的服务上
c. 正式发送请求
我们分别来看看对应的步骤,我们应该做什么操作
1.和a.在代码上是完全一样的。
if (!QDBusConnection::sessionBus().isConnected()) { fprintf(stderr, "Cannot connect to the D-Bus session bus./n" "To start it, run:/n" "/teval `dbus-launch --auto-syntax`/n"); return 1; }
sessionBus()是一个静态函数,返回当前的一个QDBusConnection连接,如果原来没有则创建一个.
2. 使用registerService函数去注册,SERVICE_NAME可以随便写,我这里写的是com.cuteqt.blogexample
if (!QDBusConnection::sessionBus().registerService(SERVICE_NAME)) { fprintf(stderr, "%s/n", qPrintable(QDBusConnection::sessionBus().lastError().message())); exit(1); }
执行完这一步后,你可以使用Qt带的工具,qdbusviewer就能看到com.cuteqt.blogexample已经注册上了
3. qtqt是我的QtQt类的几个对象,将其注册到总线上,这个提供服务的就是QtQt的类函数
QtQt qtqt; QDBusConnection::sessionBus().registerObject("/", &qtqt, QDBusConnection::ExportAllSlots);
b. 这一步注意SERVICE_NAME的名字和服务器端的代码一样即可,可以判断iface.isValid()
QDBusInterface iface(SERVICE_NAME, "/", "", QDBusConnection::sessionBus());
c. 真正发出具体的总线服务内容请求
QDBusReplyreply = iface.call("blogurl","bug"); if (reply.isValid()) { printf("Reply was: %s/n", qPrintable(reply.value())); return 0; } else{ fprintf(stderr, "Call failed: %s/n", qPrintable(reply.error().message())); return 1; }
我们注意这个blogurl()请求名字就是我们在服务器端注册对象qtqt的类函数,bug是我们传送过去的参数
完整源码下载请点击
服务器端和请求端在一个应用里。运行的时候将一份可执行档拷贝名字为client的就可以。先运行服务端,再运行client。
代码就50几行,很好理解,能演示功能。但不鲁棒:)