QtDBus是一個使用D-Bus協議進行進程間通訊的僅在Unix運行的庫,是對D-Bus底層API的封裝實現。
QtDBus模塊提供了使用Qt信號槽機制擴展的接口。要使用QtDBus模塊,須要在代碼中加入如下代碼:node
#include <QtDBus>
若是使用qmake構建程序,須要在工程文件中增長下列代碼來連接QtDBus庫:程序員
QT += qdbus
D-Bus有一種基於幾種原生與在數組和結構中的原生類型組成的複合類型的擴展類型系統。QtDBus模塊經過QDBusArgument類實現了類型系統,容許用戶經過總線發送和接收每一種C++類型。編程
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。 session
D-Bus指定由原生類型聚合而成的三種複合類型:ARRAY、STRUCT和 maps/dictionaries。ARRAY零個或多個相同元素的集合,STRUCT是由不一樣類型的固定數量的元素組成的集合,Maps or dictionaries是元素對的數組,一個map中能夠有零個或多個元素。異步
爲了在QtDBus模塊使用自定義類型,自定義類性必須使用Q_DECLARE_METATYPE()聲明爲Qt元類型,使用qDBusRegisterMetaType()函數註冊。流操做符會被註冊系統自動找到。
QtDBus模塊爲Qt容器類使用數組和map提供了模板特化,例如QMap和QList,沒必要實現流操做符函數。對於其它的類型,流操做符必須顯示實現。async
QtDBus定義的全部類型能用於經過總線發送和接收消息。不能使用上述類型以外的任何類型,包括typedefs定義的列表類型,如ide
QList<QVariant>`和`QMap< QString,QVariant>
QDBusMessage類表示D-Bus總線發送或接收的一個消息。
QDBusMessage對象表明總線上四種消息類型中的一種,四種消息類型以下:
A、Method calls
B、Method return values
C、Signal emissions
D、Error codes
可使用靜態函數createError()、createMethodCall()、createSignal()建立消息。使用QDBusConnection::send() 函數發送消息。函數
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總線系統知道的本機IDQDBusConnection 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;若是名字已經在其它應用被註冊,則註冊失敗。工具
QDBusInterface是遠程對象接口的代理。
QDBusInterface是一種通用的訪問器類,用於調用遠程對象,鏈接到遠程對象導出的信號,獲取/設置遠程屬性的值。當沒有生成表示遠程接口的生成代碼時時,QDBusInterface類對遠程對象的動態訪問很是有用。
調用一般是經過使用call()函數來實現,call函數構造消息,經過總線發送消息,等待應答並解碼應答。信號使用QObject::connect()函數進行鏈接。最終,使用QObject::property()和QObject::setProperty()函數對屬性進行訪問。
QDBusReply類用於存儲對遠程對象的方法調用的應答。
一個QDBusReply對象是方法調用的應答QDBusMessage對象的一個子集。QDBusReply對象只包含第一個輸出參數或錯誤代碼,並由QDBusInterface派生類使用,以容許將錯誤代碼返回爲函數的返回參數。
QDBusReply<QString> reply = interface->call("RemoteMethod"); if (reply.isValid()) // use the returned value useValue(reply.value()); else // call failed. Show an error condition. showError(reply.error());
對於沒有輸出參數或返回值的遠程調用,使用isValid()函數測試應答是否成功。
QDBusAbstractAdaptor類使用D-Bus Adaptor基類。
QDBusAbstractAdaptor類是用於使用D-Bus向外部提供接口的全部對象的起點。能夠經過將一個或多個派生自QDBusAbstractAdaptor的類附加到一個普通QObject對象上,使用QDBusConnection::registerObject註冊QObject對象能夠實現。QDBusAbstractAdaptor是一個輕量級封裝,主要用於中繼調用實際對象及其信號。
每一個QDBusAbstractAdaptor派生類都應該使用類定義中的Q_CLASSINFO宏來定義D-Bus接口。注意,這種方式只有一個接口能夠暴露。
QDBusAbstractAdaptor使用了信號、槽、屬性的標準QObject機制來決定哪些信號、槽、屬性被暴露到總線。任何QDBusAbstractAdaptor派生類發送的信號經過任何D-Bus鏈接自動中繼到註冊的對象上。
QDBusAbstractAdaptor派生類對象必須使用new建立在堆上,沒必要由用戶刪除。
QDBusAbstractInterface是QtDBus模塊中容許訪問遠程接口的全部D-Bus接口的基類。
自動生成的代碼類也繼承自QDBusAbstractInterface,此描述的全部方法在生成的代碼中也有效。除了此處的描述,生成代碼類爲遠程方法提供了成員函數,容許在編譯時檢查正確參數和返回值,以及匹配的屬性類型和匹配的信號參數。
QDBusPendingCall asyncCall(const QString & method, const QVariant & arg1 = QVariant(), const QVariant & arg2 = QVariant(), const QVariant & arg3 = QVariant(), const QVariant & arg4 = QVariant(), const QVariant & arg5 = QVariant(), const QVariant & arg6 = QVariant(), const QVariant & arg7 = QVariant(), const QVariant & arg8 = QVariant())
調用本接口中的method方法,傳遞參數到遠程的method。
要調用的參數會經過D-Bus輸入參數傳遞到遠程方法,返回的QDBusPendingCall對象用於定義應答信息。
本函數最多有8個參數,若是參數多於8個,或是傳遞可變數量的參數,使用asyncCallWithArgumentList()函數。
QString value = retrieveValue(); QDBusPendingCall pcall = interface->asyncCall(QLatin1String("Process"), value); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(callFinishedSlot(QDBusPendingCallWatcher*)));
QDBusArgument類用於整理和分發D-Bus參數。QDBusArgument用於經過D-Bus發送參數到遠程應用,並接收返回。
QDBusArgument是QtDBus類型系統的核心類,QtDBus類型系統用於解析和原生類型。複合類型能夠經過在數組、詞典或結構中使用一個或多個原生類型建立。
下列代碼展現了使用QtDBus類型系統構造的包含一個整數和字符串的結構。
struct MyStructure { int count; QString name; }; Q_DECLARE_METATYPE(MyStructure) // Marshall the MyStructure data into a D-Bus argument QDBusArgument &operator<<(QDBusArgument &argument, const MyStructure &mystruct) { argument.beginStructure(); argument << mystruct.count << mystruct.name; argument.endStructure(); return argument; } // Retrieve the MyStructure data from the D-Bus argument const QDBusArgument &operator>>(const QDBusArgument &argument, MyStructure &mystruct) { argument.beginStructure(); argument >> mystruct.count >> mystruct.name; argument.endStructure(); return argument; }
在QDBusArgument使用這個結構前,必須使用qDBusRegisterMetaType()函數進行註冊。所以,在程序中應該則增長以下代碼:qDBusRegisterMetaType<MyStructure>();
一旦註冊,類型能夠在呼出方法調用(QDBusAbstractInterface::call())、來自注冊對象的信號發射或來自遠程應用的傳入調用。
QDBusConnectionInterface類提供了對D-Bus總線服務的訪問。
D-Bus總線服務端中提供了一個特殊的接口org.freedesktop.DBus,容許客戶端運行訪問總線的某些屬性,例如當前鏈接的客戶端列表,QDBusConnectionInterface類提供對org.freedesktop.DBus接口的訪問。
本類中最經常使用的是使用registerService()和unregisterService()在總線上註冊和註銷服務名。
QDBusConnectionInterface類定義四個信號,在總線上有服務狀態變化時發送。
void callWithCallbackFailed(const QDBusError & error, const QDBusMessage & call) void serviceOwnerChanged(const QString & name, const QString & oldOwner, const QString & newOwner) void serviceRegistered(const QString & serviceName) void serviceUnregistered(const QString & serviceName)
QDBusVariant類使程序員可以識別由D-Bus類型系統提供的Variant類型。一個使用整數、D-Bus變體類型和字符串做爲參數的D-Bus函數可使用以下的參數列表調用。
QList<QVariant> arguments; arguments << QVariant(42) << QVariant::fromValue(QDBusVariant(43)) << QVariant("hello"); myDBusMessage.setArguments(arguments);
當D-Bus函數返回一個D-Bus變體類型時,可使用以下方法獲取:
// call a D-Bus function that returns a D-Bus variant QVariant v = callMyDBusFunction(); // retrieve the D-Bus variant QDBusVariant dbusVariant = qvariant_cast<QDBusVariant>(v); // retrieve the actual value stored in the D-Bus variant QVariant result = dbusVariant.variant();
QDBusVariant中的QVariant須要區分一個正常的D-Bus值和一個QDBusVariant中的值。
qdbusviewer用於查看D-Bus總線上的服務、對象、接口以及接口的method。使用方法直接在命令行執行:qdbusviewer
qdbuscpp2xml會解析QObject派生類的C++頭文件或是源文件,生成D-Bus的內省xml文件。qdbuscpp2xml 會區分函數的輸入輸出,若是參數聲明爲const則會是輸入,不然可能會被看成輸出。
qdbuscpp2xml使用語法以下:qdbuscpp2xml [options...] [files...]
Options參數以下:
-p|-s|-m:只解析腳本化的屬性、信號、方法(槽函數)
-P|-S|-M:解析全部的屬性、信號、方法(槽函數)
-a:輸出全部的腳本化內容,等價於-psm
-A:輸出全部的內容,等價於-PSM
-o filename:輸出內容到filename文件
解析全部的方法輸出到com.scorpio.test.xml文件命令以下:qdbuscpp2xml -M test.h -o com.scorpio.test.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="com.scorpio.test.value"> <method name="maxValue"> <arg type="i" direction="out"/> </method> <method name="minValue"> <arg type="i" direction="out"/> </method> <method name="value"> <arg type="i" direction="out"/> </method> <method name="setValue"> <arg name="value" type="i" direction="in"/> </method> </interface> </node>
qdbusxml2cpp根據輸入文件中定義的接口,生成C++實現代碼。
qdbusxml2cpp能夠輔助自動生成繼承於QDBusAbstractAdaptor和QDBusAbstractInterface兩個類的實現代碼,用於進程通訊服務端和客戶端,簡化了開發者的代碼設計。
qdbusxml2cpp使用語法以下:qdbusxml2cpp [options...] [xml-or-xml-file] [interfaces...]
Options參數以下:
-a filename:輸出Adaptor代碼到filename
-c classname:使用classname做爲生成類的類名
-i filename:增長#include到輸出
-l classname:當生成Adaptor代碼時,使用classname做爲父類
-m:在cpp文件中包含 #include "filename.moc"語句
-N:不使用名稱空間
-p filename:生成Proxy代碼到filename文件
解析com.scorpio.test.xml文件,生成Adaptor類ValueAdaptor,文件名稱爲valueAdaptor.h、valueAdaptor.cpp命令行以下:qdbusxml2cpp com.scorpio.test.xml -i test.h -a valueAdaptor
解析com.scorpio.test.xml文件,生成Proxy類ComScorpioTestValueInterface,文件名稱爲testInterface.h、testInterface.cpp命令行以下:qdbusxml2cpp com.scorpio.test.xml -p testInterface
test.h文件:
#ifndef TEST_H #define TEST_H #include <QObject> class test: public QObject { Q_OBJECT //定義Interface名稱爲com.scorpio.test.value Q_CLASSINFO("D-Bus Interface", "com.scorpio.test.value") public: test(int value); public slots: int maxValue(); int minValue(); int value(); private: int m_value; }; #endif // TEST_H
test.cpp文件:
#include "test.h" test::test(int value) { m_value = value; } int test::maxValue() { return 100; } int test::minValue() { return 0; } int test::value() { return m_value; }
main.cpp文件:
#include <QCoreApplication> #include <QDBusConnection> #include <QDebug> #include <QDBusError> #include "test.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); //創建到session bus的鏈接 QDBusConnection connection = QDBusConnection::sessionBus(); //在session bus上註冊名爲com.scorpio.test的服務 if(!connection.registerService("com.scorpio.test")) { qDebug() << "error:" << connection.lastError().message(); exit(-1); } test object(60); //註冊名爲/test/objects的對象,把類Object全部槽函數導出爲object的method connection.registerObject("/test/objects", &object,QDBusConnection::ExportAllSlots); return a.exec(); }
啓動程序後,在命令行打開qdbusviewer,查看session bus。
雙擊Method方法會調用該方法。
確保com.scorpio.test服務運行在總線上。
編寫一個控制檯程序,使用消息訪問com.scorpio.test服務。
#include <QCoreApplication> #include <QDBusMessage> #include <QDBusConnection> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); //構造一個method_call消息,服務名稱爲:com.scorpio.test,對象路徑爲:/test/objects //接口名稱爲com.scorpio.test.value,method名稱爲value QDBusMessage message = QDBusMessage::createMethodCall("com.scorpio.test", "/test/objects", "com.scorpio.test.value", "value"); //發送消息 QDBusMessage response = QDBusConnection::sessionBus().call(message); //判斷method是否被正確返回 if (response.type() == QDBusMessage::ReplyMessage) { //從返回參數獲取返回值 int value = response.arguments().takeFirst().toInt(); qDebug() << QString("value = %1").arg(value); } else { qDebug() << "value method called failed!"; } return a.exec(); }
編寫一個控制檯程序,使用接口訪問com.scorpio.test服務。
#include <QCoreApplication> #include <QDBusMessage> #include <QDBusConnection> #include <QDBusReply> #include <QDBusInterface> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 建立QDBusInterface接口 QDBusInterface interface("com.scorpio.test", "/test/objects", "com.scorpio.test.value", QDBusConnection::sessionBus()); if (!interface.isValid()) { qDebug() << qPrintable(QDBusConnection::sessionBus().lastError().message()); exit(1); } //調用遠程的value方法 QDBusReply<int> reply = interface.call("value"); if (reply.isValid()) { int value = reply.value(); qDebug() << QString("value = %1").arg(value); } else { qDebug() << "value method called failed!"; } return a.exec(); }
Proxy Object提供了一種更加直觀的方式來訪問Service,如同調用本地對象的方法同樣。
生成Proxy類的流程以下:
A、使用工具qdbuscpp2xml從object.h生成XML文件;qdbuscpp2xml -M test.h -o com.scorpio.test.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="com.scorpio.test.value"> <method name="maxValue"> <arg type="i" direction="out"/> </method> <method name="minValue"> <arg type="i" direction="out"/> </method> <method name="value"> <arg type="i" direction="out"/> </method> </interface> </node>
B、使用工具qdbusxml2cpp從XML文件生成繼承自QDBusInterface的類qdbusxml2cpp com.scorpio.test.xml -p valueInterface
生成兩個文件:valueInterface.cpp和valueInterface.h
valueInterface.h文件:
/* * This file was generated by qdbusxml2cpp version 0.7 * Command line was: qdbusxml2cpp com.scorpio.test.xml -p testInterface * * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). * * This is an auto-generated file. * Do not edit! All changes made to it will be lost. */ #ifndef TESTINTERFACE_H_1526737677 #define TESTINTERFACE_H_1526737677 #include <QtCore/QObject> #include <QtCore/QByteArray> #include <QtCore/QList> #include <QtCore/QMap> #include <QtCore/QString> #include <QtCore/QStringList> #include <QtCore/QVariant> #include <QtDBus/QtDBus> /* * Proxy class for interface com.scorpio.test.value */ class ComScorpioTestValueInterface: public QDBusAbstractInterface { Q_OBJECT public: static inline const char *staticInterfaceName() { return "com.scorpio.test.value"; } public: ComScorpioTestValueInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); ~ComScorpioTestValueInterface(); public Q_SLOTS: // METHODS inline QDBusPendingReply<int> maxValue() { QList<QVariant> argumentList; return asyncCallWithArgumentList(QLatin1String("maxValue"), argumentList); } inline QDBusPendingReply<int> minValue() { QList<QVariant> argumentList; return asyncCallWithArgumentList(QLatin1String("minValue"), argumentList); } inline QDBusPendingReply<int> value() { QList<QVariant> argumentList; return asyncCallWithArgumentList(QLatin1String("value"), argumentList); } Q_SIGNALS: // SIGNALS }; namespace com { namespace scorpio { namespace test { typedef ::ComScorpioTestValueInterface value; } } } #endif
valueInterface.cpp文件:
/* * This file was generated by qdbusxml2cpp version 0.7 * Command line was: qdbusxml2cpp com.scorpio.test.xml -p testInterface * * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). * * This is an auto-generated file. * This file may have been hand-edited. Look for HAND-EDIT comments * before re-generating it. */ #include "testInterface.h" /* * Implementation of interface class ComScorpioTestValueInterface */ ComScorpioTestValueInterface::ComScorpioTestValueInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) { } ComScorpioTestValueInterface::~ComScorpioTestValueInterface() { }
調用Proxy類訪問Service以下:
#include <QCoreApplication> #include <QDBusMessage> #include <QDBusConnection> #include <QDBusReply> #include <QDBusInterface> #include <QDebug> #include "testInterface.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 初始化自動生成的Proxy類com::scorpio::test::value com::scorpio::test::value test("com.scorpio.test", "/test/objects", QDBusConnection::sessionBus()); // 調用value方法 QDBusPendingReply<int> reply = test.value(); //qdbusxml2cpp生成的Proxy類是採用異步的方式來傳遞Message, //因此須要調用waitForFinished來等到Message執行完成 reply.waitForFinished(); if (reply.isValid()) { int value = reply.value(); qDebug() << QString("value = %1").arg(value); } else { qDebug() << "value method called failed!"; } return a.exec(); }
能夠直接把test類註冊爲消息總線上的一個Object,但QT4不推薦。QT4推薦使用Adapter來註冊Object。
大多數狀況下,可能只須要把自定義的類裏的方法有選擇的發佈到消息總線上,使用Adapter能夠很方便的實現選擇性發布。
生成Adapter類的流程以下:
A、使用工具 qdbuscpp2xml從test.h生成XML文件qdbuscpp2xml -M test.h -o com.scorpio.test.xml
B、編輯com.scorpio.test.xml,選擇須要發佈的method,不須要發佈的刪除。
C、使用工具qdbusxml2cpp從XML文件生成繼承自QDBusInterface的類qdbusxml2cpp com.scorpio.test.xml -i test.h -a valueAdaptor
生成兩個文件:valueAdaptor.cpp和valueAdaptor.h
valueAdaptor.h文件:
/* * This file was generated by qdbusxml2cpp version 0.7 * Command line was: qdbusxml2cpp com.scorpio.test.xml -i test.h -a valueAdaptor * * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). * * This is an auto-generated file. * This file may have been hand-edited. Look for HAND-EDIT comments * before re-generating it. */ #ifndef VALUEADAPTOR_H_1526742670 #define VALUEADAPTOR_H_1526742670 #include <QtCore/QObject> #include <QtDBus/QtDBus> #include "test.h" class QByteArray; template<class T> class QList; template<class Key, class Value> class QMap; class QString; class QStringList; class QVariant; /* * Adaptor class for interface com.scorpio.test.value */ class ValueAdaptor: public QDBusAbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.scorpio.test.value") Q_CLASSINFO("D-Bus Introspection", "" " <interface name=\"com.scorpio.test.value\">\n" " <method name=\"maxValue\">\n" " <arg direction=\"out\" type=\"i\"/>\n" " </method>\n" " <method name=\"minValue\">\n" " <arg direction=\"out\" type=\"i\"/>\n" " </method>\n" " </interface>\n" "") public: ValueAdaptor(QObject *parent); virtual ~ValueAdaptor(); public: // PROPERTIES public Q_SLOTS: // METHODS int maxValue(); int minValue(); Q_SIGNALS: // SIGNALS }; #endif
valueAdaptor.cpp文件:
/* * This file was generated by qdbusxml2cpp version 0.7 * Command line was: qdbusxml2cpp com.scorpio.test.xml -i test.h -a valueAdaptor * * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). * * This is an auto-generated file. * Do not edit! All changes made to it will be lost. */ #include "valueAdaptor.h" #include <QtCore/QMetaObject> #include <QtCore/QByteArray> #include <QtCore/QList> #include <QtCore/QMap> #include <QtCore/QString> #include <QtCore/QStringList> #include <QtCore/QVariant> /* * Implementation of adaptor class ValueAdaptor */ ValueAdaptor::ValueAdaptor(QObject *parent) : QDBusAbstractAdaptor(parent) { // constructor setAutoRelaySignals(true); } ValueAdaptor::~ValueAdaptor() { // destructor } int ValueAdaptor::maxValue() { // handle method call com.scorpio.test.value.maxValue int out0; QMetaObject::invokeMethod(parent(), "maxValue", Q_RETURN_ARG(int, out0)); return out0; } int ValueAdaptor::minValue() { // handle method call com.scorpio.test.value.minValue int out0; QMetaObject::invokeMethod(parent(), "minValue", Q_RETURN_ARG(int, out0)); return out0; }
調用Adaptor類註冊Object對象以下:
#include <QCoreApplication> #include <QDBusConnection> #include <QDebug> #include <QDBusError> #include "test.h" #include "valueAdaptor.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QDBusConnection connection = QDBusConnection::sessionBus(); test object(60); //ValueAdaptor是qdbusxml2cpp生成的Adaptor類 ValueAdaptor valueAdaptor(&object); if (!connection.registerService("com.scorpio.test")) { qDebug() << connection.lastError().message(); exit(1); } connection.registerObject("/test/objects", &object); return a.exec(); }
使用qdbusviewer查看發佈的method。
D-Bus系統提供了一種機制能夠在訪問某個service時,自動把應用程序運行起來。
須要在/usr/share/dbus-1/services下面創建com.scorpio.test.service文件,文件的內容以下:
[D-BUS Service] Name=com.scorpio.test Exec=/path/to/scorpio/test
在訪問test的method前,沒必要手動運行應用程序。