通過前面的介紹,相信對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:時間有限,後面補充