Qt高级——QtDBus快速入门
一、QtDBus简介
QtDBus是一个使用D-Bus协议进行进程间通信的仅在Unix运行的库,是对D-Bus底层API的封装实现。
QtDBus模块提供了使用Qt信号槽机制扩展的接口。要使用QtDBus模块,需要在代码中加入以下代码:
#include
如果使用qmake构建程序,需要在工程文件中增加下列代码来链接QtDBus库:
QT += qdbus
二、QtDBus类型系统
1、QtDBus类型系统简介
D-Bus有一种基于几种原生与在数组和结构中的原生类型组成的复合类型的扩展类型系统。QtDBus模块通过QDBusArgument类实现了类型系统,允许用户通过总线发送和接收每一种C++类型。
2、原生类型
QtDBus通过QDBusArgument支持原生类型,不需要特殊的定制。
Qt类型 D-Bus类型
uchar BYTE
bool BOOLEAN
short INT16
ushort UINT16
int INT32
uint UINT32
qlonglong INT64
qulonglong UINT64
double DOUBLE
QString STRING
QDBusVariant VARIANT
QDBusObjectPath OBJECT_PATH
QDBusSignature SIGNATURE
除了原生类型,QDBusArgument也支持在Qt应用中广泛使用的两种非原生类型,QStringList和QByteArray。
3、复合类型
D-Bus指定由原生类型聚合而成的三种复合类型:ARRAY、STRUCT和 maps/dictionaries。ARRAY零个或多个相同元素的集合,STRUCT是由不同类型的固定数量的元素组成的集合,Maps or dictionaries是元素对的数组,一个map中可以有零个或多个元素。
4、扩展类型系统
为了在QtDBus模块使用自定义类型,自定义类性必须使用Q_DECLARE_METATYPE()声明为Qt元类型,使用qDBusRegisterMetaType()函数注册。流操作符会被注册系统自动找到。
QtDBus模块为Qt容器类使用数组和map提供了模板特化,例如QMap和QList,不必实现流操作符函数。对于其它的类型,流操作符必须显示实现。
5、类型系统使用
QtDBus定义的所有类型能用于通过总线发送和接收消息。不能使用上述类型之外的任何类型,包括typedefs定义的列表类型,如
QList`和`QMap< QString,QVariant>
三、QtDBus常用类
1、QDBusMessage
QDBusMessage类表示D-Bus总线发送或接收的一个消息。
QDBusMessage对象代表总线上四种消息类型中的一种,四种消息类型如下:
A、Method calls
B、Method return values
C、Signal emissions
D、Error codes
可以使用静态函数createError()、createMethodCall()、createSignal()创建消息。使用QDBusConnection::send() 函数发送消息。
2、QDBusConnection
QDBusConnection代表到D-Bus总线的一个连接,是一个D-Bus会话的起始点。通过QDBusConnection连接对象,可以访问远程对象、接口,连接远程信号到本地槽函数,注册对象等。
D-Bus连接通过connectToBus()函数创建,connectToBus()函数会创建一个到总线服务端的连接,完成初始化工作,并关联一个连接名到连接。
使用disconnectFromBus()函数会断开连接。一旦断开连接后,调用connectToBus()函数将不会重建连接,必须创建新的QDBusConnection实例。
作为两种最常用总线类型的辅助,sessionBus()和systemBus()函数分别创建到会话在总线和系统总线的连接并返回,会在初次使用时打开,在QCoreApplication析构函数调用时断开。
D-Bus支持点对点通信,不必使用总线服务。两个应用程序可以直接交流和交换消息。可以通过传递一个地址到connectToBus()函数实现。
QDBusConnection connectToBus(BusType type, const QString & name)
打开一个type类型的连接,并关联name连接名,返回关联本连接的QDBusConnection对象。
QDBusConnection connectToBus(const QString & address, const QString & name)
打开一个地址为address的私有总线,并关联name连接名,返回关联本连接的QDBusConnection对象。
QDBusConnection connectToPeer(const QString & address, const QString & name)
打开一个点对点的连接到address地址,并关联name连接名,返回关联本连接的QDBusConnection对象。
void disconnectFromBus(const QString & name)
关闭名为name的总线连接
void disconnectFromPeer(const QString & name)
关闭名为name的对等连接
QByteArray localMachineId()
返回一个D-Bus总线系统知道的本机ID
QDBusConnection sender()
返回发送信号的连接
QDBusConnection sessionBus()
返回一个打开到session总线的QDBusConnection对象
QDBusConnection systemBus()
返回一个打开到system总线的QDBusConnection对象
QDBusPendingCall asyncCall(const QDBusMessage & message, int timeout = -1)const
发送message消息到连接,并立即返回。本函数只支持method调用。返回一个用于追踪应答的QDBusPendingCall对象。
QDBusMessage call(const QDBusMessage & message, QDBus::CallMode mode = QDBus::Block, int timeout = -1 ) const
通过本连接发送消息message,并且阻塞,等待应答。
bool registerObject(const QString & path, QObject * object, RegisterOptions options = ExportAdaptors)
注册object对象到路径path,options选项指定由多少对象会被暴露到D-Bus总线,如果注册成功,返回true。
bool registerService(const QString & serviceName)
试图在D-Bus总线上注册serviceName服务,如果注册成功,返回true;如果名字已经在其它应用被注册,则注册失败。
3、QDBusInterface
QDBusInterface是远程对象接口的代理。
QDBusInterface是一种通用的访问器类,用于调用远程对象,连接到远程对象导出的信号,获取/设置远程属性的值。当没有生成表示远程接口的生成代码时时,QDBusInterface类对远程对象的动态访问非常有用。
调用通常是通过使用call()函数来实现,call函数构造消息,通过总线发送消息,等待应答并解码应答。信号使用QObject::connect()函数进行连接。最终,使用QObject::property()和QObject::setProperty()函数对属性进行访问。
4、QDBusReply
QDBusReply类用于存储对远程对象的方法调用的应答。
一个QDBusReply对象是方法调用的应答QDBusMessage对象的一个子集。QDBusReply对象只包含第一个输出参数或错误代码,并由QDBusInterface派生类使用,以允许将错误代码返回为函数的返回参数。
QDBusReply reply = interface->call("RemoteMethod");
if (reply.isValid())
// use the returned value
useValue(reply.value());
else
// call failed. Show an err