注意:
QT += dbus
服务端参数不能是引用。
QString testString(QString& name) 不行
服务端:
#include <QObject>
#include <QDBusConnection>
#include <QDBusError>
#include <QDebug>
class CTestDbus: public QObject
{
Q_OBJECT
//定义Interface名称为com.Interface.CTestDbus
Q_CLASSINFO("D-Bus Interface", "com.Interface.CTestDbus")
public:
explicit CTestDbus(QObject* parent = nullptr):QObject(parent){}
public slots:
QString testString(QString name)
{
QString str = "testString : " + name;
qDebug() <<"Server: " << str;
emit testSignal(9);
return str;
}
signals:
void testSignal(int);
};
//建立到session bus的连接
QDBusConnection connection = QDBusConnection::sessionBus();
//在session bus上注册名为com.Server.Server1的服务
if(!connection.registerService("com.Server.Server1"))
{
qDebug() << "error:" << connection.lastError().message();
return;
}
CTestDbus *obj = new CTestDbus;
//注册名为/com/ObjectPath/CTestDbus的对象,把类Object所有槽函数和信号导出为object的method
if (!connection.registerObject("/com/ObjectPath/CTestDbus", obj,
QDBusConnection::ExportAllSlots|QDBusConnection::ExportAllSignals))
{
qDebug() << "error:" << connection.lastError().message();
return;
}
客户端:
#include <QMainWindow>
#include <QMainWindow>
#include <QDBusConnection>
#include <QDBusError>
#include <QDBusPendingCallWatcher>
#include <QDBusInterface>
#include <QDBusPendingReply>
#include <QDBusReply>
#include <QDebug>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
public:
void dbusclient();
signals:
public slots:
void testSlot(int value);
void callFinishedSlot(QDBusPendingCallWatcher *call);
};
void MainWindow::dbusclient()
{
//
#ifdef METHOD1 //远程服务调用方法一
//构造一个method_call消息,服务名称为:com.Server.Server1,对象路径为:/com/ObjectPath/CTestDbus
//接口名称为com.Interface.CTestDbus,method名称为testString
QDBusMessage message = QDBusMessage::createMethodCall("com.Server.Server1",
"/com/ObjectPath/CTestDbus",
"com.Interface.CTestDbus",
"testString");
// 传递参数
message << QString("lalala");
//发送消息
QDBusMessage response = QDBusConnection::sessionBus().call(message);
//判断method是否被正确返回
if (response.type() == QDBusMessage::ReplyMessage)
{
//从返回参数获取返回值
QString value = response.arguments().takeFirst().toString();
qDebug() << QString("Client get return value = %1").arg(value);
}
else
{
qDebug() << "value method called failed!";
}
//
#elif METHOD2 //远程服务调用方法二
// 创建QDBusInterface接口
QDBusInterface interface("com.Server.Server1", "/com/ObjectPath/CTestDbus",
"com.Interface.CTestDbus",
QDBusConnection::sessionBus());
if (!interface.isValid())
{
qDebug() << qPrintable(QDBusConnection::sessionBus().lastError().message());
exit(1);
}
//调用远程的testString方法,第一个参数为lalala2222
//QDBusReply<QString>返回值类型和setName返回值类型保持一致
//call是同步调用,远程方法返回后才继续往下执行。
QDBusReply<QString> reply = interface.call("testString", "lalala2222"); //阻塞,直到远程方法调用完成。
if (reply.isValid())
{
QString value = reply.value();
qDebug() << QString("debus value = %1").arg(value);
}
else
{
qDebug() << "value method called failed!";
}
//
#else// 远程服务调用方法三,异步调用
// 异步调用
// 创建QDBusInterface接口
QDBusInterface interface("com.Server.Server1", "/com/ObjectPath/CTestDbus",
"com.Interface.CTestDbus",
QDBusConnection::sessionBus());
if (!interface.isValid())
{
qDebug() << qPrintable(QDBusConnection::sessionBus().lastError().message());
exit(1);
}
{
// 方法一:接收服务端的信号,连接槽函数。服务器对象必须注册QDBusConnection::ExportAllSignals
// if (!QDBusConnection::sessionBus().connect("com.Server.Server1",
// "/com/ObjectPath/CTestDbus",
// "com.Interface.CTestDbus",
// "testSignal", this,
// SLOT(testSlot(int))))
//方法二: 接收服务端的信号,连接槽函数。服务器对象必须注册QDBusConnection::ExportAllSignals
QDBusInterface *pinterface = new QDBusInterface ("com.Server.Server1",
"/com/ObjectPath/CTestDbus",
"com.Interface.CTestDbus",
QDBusConnection::sessionBus());
QObject::connect(pinterface, SIGNAL(testSignal(int)), this, SLOT(testSlot(int)));
}
// 这里不阻塞,异步调用。
QDBusPendingCall async = interface.asyncCall("testString", "lalala33333");
// 等待结束,async.waitForFinished ()
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);
QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
this, SLOT(callFinishedSlot(QDBusPendingCallWatcher*)));
#endif
}
void MainWindow::testSlot(int value)
{
qDebug() << "testSlot = " << value;
}
void MainWindow::callFinishedSlot(QDBusPendingCallWatcher *call)
{
QDBusPendingReply<QString> reply = *call;
if (!reply.isError()) {
QString name= reply.argumentAt<0>();
qDebug()<<"QDBusPendingReply name = "<<name;
}
call->deleteLater();
}