QDbus 用法实例

参考网站:https://www.jianshu.com/p/438c9d2594f1

服务端:

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();
    QString setName(QString name);
signals:
    void signals_process_value(int);
private:
    int m_value;
    QString m_name;
};

#endif // TEST_H
test.cpp

#include "test.h"
#include <QDebug>
#include <QThread>
test::test(int value)
{
    m_value = value;
}

int test::maxValue()
{
    return 100;
}
int test::minValue()
{
    return 0;
}
int test::value()
{
    return m_value;
}

QString test::setName(QString name)
{
    m_name = name;
    qDebug() << "setname= " <<name;
    for (int i = 1; i < 5; i++)
    {
        emit signals_process_value(i);
        QThread::sleep(1);
    }
    return name;
}

 

main.cpp

void MainWindow::dbusServer()
{
    //建立到session bus的连接
    QDBusConnection connection = QDBusConnection::sessionBus();
    //在session bus上注册名为com.scorpio.test的服务
    if(!connection.registerService("com.scorpio.test"))
    {
        qDebug() << "error:" << connection.lastError().message();
        return;
    }
    test *object = new test(60);
    //注册名为/test/objects的对象,把类Object所有槽函数和信号导出为object的method
    if (!connection.registerObject("/home/lyb/objects", object,QDBusConnection::ExportAllSlots|QDBusConnection::ExportAllSignals))
    {
        qDebug() << "error:" << connection.lastError().message();
        return;
    }
}

 

客户端:

MainWindow .h

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void dbusclient();
public slots:
    void slots_process_value(int);

private:
    Ui::MainWindow *ui;
};
MainWindow.cpp

//#define METHOD1
void MainWindow::dbusclient()
{
//////////////////////////////////////////////////////////////////////////////
#ifdef METHOD1 //远程服务调用方法一
        //构造一个method_call消息,服务名称为:com.scorpio.test,对象路径为:/test/objects
        //接口名称为com.scorpio.test.value,method名称为value
        QDBusMessage message = QDBusMessage::createMethodCall("com.scorpio.test",
                               "/home/lyb/objects",
                               "com.scorpio.test.value",
                               "setName");

        // 传递参数
        message << QString("wangjian");

        //发送消息
        QDBusMessage response = QDBusConnection::sessionBus().call(message);
        //判断method是否被正确返回
        if (response.type() == QDBusMessage::ReplyMessage)
        {
            //从返回参数获取返回值
            QString value = response.arguments().takeFirst().toString();
            qDebug() << QString("dbus value =  %1").arg(value);
        }
        else
        {
            qDebug() << "value method called failed!";
        }

//////////////////////////////////////////////////////////////////////////////
#elif METHOD2  //远程服务调用方法二
    // 创建QDBusInterface接口
       QDBusInterface interface("com.scorpio.test", "/home/lyb/objects",
                                "com.scorpio.test.value",
                                QDBusConnection::sessionBus());
       if (!interface.isValid())
       {
           qDebug() << qPrintable(QDBusConnection::sessionBus().lastError().message());
           exit(1);
       }
       //调用远程的setName方法,第一个参数为testname
       //QDBusReply<QString>返回值类型和setName返回值类型保持一致
       //call是同步调用,远程方法返回后才继续往下执行。
       QDBusReply<QString> reply = interface.call("setName", "testname"); //阻塞,直到远程方法调用完成。
       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.scorpio.test", "/home/lyb/objects",
                            "com.scorpio.test.value",
                            QDBusConnection::sessionBus());
   if (!interface.isValid())
   {
       qDebug() << qPrintable(QDBusConnection::sessionBus().lastError().message());
       exit(1);
   }

   {
        // 方法一:接收服务端的信号,连接槽函数。服务器对象必须注册QDBusConnection::ExportAllSignals
        //   if (!QDBusConnection::sessionBus().connect("com.scorpio.test", "/home/lyb/objects",
        //                                             "com.scorpio.test.value",
        //                                             "signals_process_value", this,
        //                                             SLOT(slots_process_value(int))))

       //方法二: 接收服务端的信号,连接槽函数。服务器对象必须注册QDBusConnection::ExportAllSignals
       QDBusInterface *pinterface = new QDBusInterface ("com.scorpio.test", "/home/lyb/objects",
                 "com.scorpio.test.value",QDBusConnection::sessionBus());
       QObject::connect(pinterface, SIGNAL(signals_process_value(int)), this, SLOT(slots_process_value(int)));
  }

   // 这里不阻塞,异步调用。
    QDBusPendingCall async = interface.asyncCall("setName", "Brion");

    // 等待结束,async.waitForFinished ()
    QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);

    QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                      this, SLOT(callFinishedSlot(QDBusPendingCallWatcher*)));

#endif
}

void MainWindow::callFinishedSlot(QDBusPendingCallWatcher *call)
{
     QDBusPendingReply<QString> reply = *call;
     if (!reply.isError()) {
         QString name= reply.argumentAt<0>();
         qDebug()<<"QDBusPendingReply name = "<<name;
    }
     call->deleteLater();
}

void MainWindow::slots_process_value(int value)
{
    qDebug() << "slots_process_value = " << value;
}

 

posted @ 2020-06-16 17:51  wjbooks  阅读(3181)  评论(0编辑  收藏  举报