通过前面的介绍,相信对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:时间有限,后面补充