Qt D-Bus的簡單應用

通過前面的介紹,相信對Qt D-Bus有了一定的瞭解,下面來實現一個簡單的進程間函數調用的demo,對Qt D-Bus適配器和接口等進行詳細的講解和運用。

我們先實現一個服務端進程DBus_Server,服務端代碼如下: 注,要使用D-Bus需要在pro文件加上dbus即 QT += dbus

定義接口文件:

#ifndef CALHELLO_H
#define CALHELLO_H

#include <QDebug>
#include <QObject>

class CallHello :public QObject
{
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface", "com.example.dbus.CallInterface")

public:
    CallHello(){}
    ~CallHello(){}

Q_SIGNALS:
    void Sig_SayBey();
    void Sig_SayHello();
    void Sig_SayAbout(QString);

public Q_SLOTS:
    void SayHello()
    {
        qDebug() << "Hello D-Bus";
        emit Sig_SayHello();
    }
    void SayBey()
    {
        qDebug() << "Bey D-Bus";
        emit Sig_SayBey();
    }

    QString SayAbout(QString str)
    {
        QString strCont = "D-Bus " + str;
        emit Sig_SayAbout(strCont);
        return strCont;

    }
};

#endif // CALHELLO_H

根據接口文件生成xml解析文件,然後再用Qt D-Bus XML compiler工具生成適配器文件和接口代理文件。

qdbuscpp2xml CallHello.h -A -o CallHello.xml

qdbusxml2cpp CallHello.xml -a CallHelloAdpator

qdbusxml2cpp CallHello.xml -p CallHelloInterface

將生成的適配器文件添加到服務端工程中,項目目錄如下:

直接在MainWindow創建服務,代碼如下:

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
class CallHello;
class CallInterfaceAdaptor;
QT_END_NAMESPACE

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    CallHello *m_pCallHello;
    CallInterfaceAdaptor *m_pAdpator;
};

#endif // MAINWINDOW_H

MainWindow.cpp

#include "CallHello.h"
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "CallHelloAdpator.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_pCallHello(new CallHello())
, m_pAdpator(new CallInterfaceAdaptor(m_pCallHello))
{
    ui->setupUi(this);
    QDBusConnection session = QDBusConnection::sessionBus();
    session.registerService("com.dbus.hello");
    session.registerObject("/", m_pCallHello);

    connect(m_pCallHello, &CallHello::Sig_SayBey, [&]{
        ui->label->setText(tr("SayBey Clicked"));
    });

    connect(m_pCallHello, &CallHello::Sig_SayHello, this, [&]{
        ui->label->setText(tr("SayHello Clicked"));
    });

    connect(m_pCallHello, &CallHello::Sig_SayAbout, [&](QString strCont){
        ui->label->setText(tr("SayAbout: %1").arg(strCont));
    });
}

MainWindow::~MainWindow()
{
    delete ui;
    delete m_pCallHello;
}

現在運行服務端並運行qdbusviewer查看是否創建了 “com.dbus.hello” 服務。如下圖:

下面創建客戶端進程:DBus_Client,將生成的接口代理文件CallHelloInterface 添加到客戶端工程

目錄結構如下圖,

然後直接在MainWindow 申請服務,代碼如下:

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include "CallHelloInterface.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private Q_SLOTS:
    void Slot_SayBeyBtnClicked();
    void Slot_SayHelloBtnClicked();
    void Slot_SayAboutBtnClicked();

private:
    Ui::MainWindow *ui;
    com::example::dbus::CallInterface *m_pInter;
};

#endif // MAINWINDOW_H

MainWindow.cpp

#include <QDebug>

#include "MainWindow.h"
#include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_pInter = new com::example::dbus::CallInterface("com.dbus.hello","/",QDBusConnection::sessionBus(), this);
    connect(ui->SayBeyBtn, &QPushButton::clicked, this, &MainWindow::Slot_SayBeyBtnClicked);
    connect(ui->SayHelloBtn, &QPushButton::clicked, this, &MainWindow::Slot_SayHelloBtnClicked);
    connect(ui->SayAboutBtn, &QPushButton::clicked, this, &MainWindow::Slot_SayAboutBtnClicked);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::Slot_SayBeyBtnClicked()
{
    m_pInter->SayBey();
}

void MainWindow::Slot_SayHelloBtnClicked()
{
    m_pInter->SayHello();
}

void MainWindow::Slot_SayAboutBtnClicked()
{
    QDBusPendingReply<QString> reply = m_pInter->SayAbout(ui->lineEdit->text());
    reply.waitForFinished();
    qDebug() << reply.value();
    ui->label->setText(reply.value());
}

運行效果如下圖:

PS:時間有限,後面補充

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章