【Qt进程通信】Linux下通过使用QtDBus进行进程通信,通过QtDus调用其他进程中的方法

通过QtDBus,可以将Qt的信号槽机制上升到不同进程之间通信。

使用系统:银河麒麟
Qt版本:4.6.1

网上教程说,qmake编译需要将QT+= qDbus添加到pro工程里

添加后提示找不到该模块,在包含头文件后使用函数时报了找不到定义的编译错误。

经过一下午的排查尝试,最后发现在pro工程里添加

QT += dbus

便能正确的将模块加载进来了。

示例程序:
本程序中服务端运行后弹出窗口,此时运行发送端将关闭服务端弹出的窗口。
调用端:
widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusError>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

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

main.cpp

//#include "widget.h"
#include <QCoreApplication>
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusError>
#include <QtDBus/QDBusMessage>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 //   Widget w;
 //   w.show();
    //构造一个消息

    QDBusMessage message = QDBusMessage::createMethodCall("com.scorpio.test",
                             "/home/kylin",
                             "com.scorpio.test.close",
                             "closeWidget");
     //发送消息
    QDBusMessage response = QDBusConnection::sessionBus().call(message);
    if(response.type()==QDBusMessage::ReplyMessage)
    {
        int value = response.arguments().takeFirst().toInt();
        qDebug()<<QString("value==%1").arg(value);
    }
    else
    {
        qDebug()<<"value method called failed:"<<response.type();
    }
  //  return 0;

    return a.exec();
}

受控服务端:
main.cpp


#include <QApplication>
#include <QDebug>
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusError>
#include "widget.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    //建立到session bus的连接
    QDBusConnection connection = QDBusConnection::sessionBus();
    //在session bus上注册名为com.scorpio.test的服务
    if(!connection.registerService("com.scorpio.test"))
    {
        qDebug()<<connection.lastError().message();
        exit(-1);
    }
    Widget w;
    connection.registerObject("/home/kylin",&w,QDBusConnection::ExportAllSlots);
    w.show();
    return a.exec();
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QObject>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface","com.scorpio.test.close")
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
public slots:
    int closeWidget();
private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

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

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

int Widget::closeWidget()
{
    this->close();
    return 1;
}

参数解释:

对象路径
像网络主机,应用程序通过导出对象为其它应用程序提供特定服务。这些对象按层次组织,非常类似类的父子关系,派生自 QObject 占有。不管怎样,一种区别是存在根对象概念 (所有对象具有最终父级)。
若继续与 Web 服务进行类比,对象路径等同于 URL 的路径部分
像它们,D-Bus 对象路径的形成类似文件系统路径名:它们是以斜杠分隔的标签,各标签的组成由字母、数字及下划线字符 ( _ )。它们必须始终以斜杠开头,且不能以斜杠结尾。

服务名称
当通过总线通信时,应用程序获得所谓的服务名称:这就是该应用程序选择被同一总线中,其它应用程序知道的方式。服务名称由 D-Bus 总线代理程序守护,用于将消息从一个应用程序路由到另一个应用程序。与服务名称类似的概念是 IP 地址和主机名:根据计算机提供给网络的服务,一台计算机通常具有一个 IP 地址,且可能具有一个或多个与其关联的主机名。
另一方面,若不使用总线,也不会使用服务名称。若再将其与计算机网络进行比较,这相当于点对点网络:由于对等方是已知的,因此不需要使用主机名来查找它 (或其 IP 地址)。
D-Bus 服务名称的格式实际上非常类似于主机名:它是由点分隔的字母和数字的序列。常见实践甚至是根据定义该服务的组织的域名,来命名一服务名称。
例如,D-Bus 服务的定义通过 freedesktop.org 且可以在总线中找到以下服务名称:

org.freedesktop.DBus

接口
接口类似 C++ 抽象类和 Java 的 interface 关键词和声明在调用者和被调用者之间建立的契约。也就是说,它们建立的方法、信号及特性的名称是可用的,及行为是双方期望的当建立通信时。
Qt 使用非常类似的机制在其 插件系统 :C++ 中的基类关联唯一标识符,通过方式 Q_DECLARE_INTERFACE () 宏。
实际上,D-Bus 接口名称的命名方式与 Qt 插件系统的建议类似:标识符的构造通常来自定义该接口的实体的域名

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值