QtDBus,使用QT DBus xml接口时未从dbus发送接收信号

时间:2019-07-16 05:17:30

标签: c++ qt dbus qtdbus

系统信息:

  • QT5.10
  • Ubuntu 16.04

使用QtDBus并使用以下XML,生成了xyz_interface.hpp

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="com.blah.XYZ">
    <signal name="Event">
        <arg name="event_json" type="s" direction="out"/>
    </signal>
    <method name="AuthenticateUser">
        <arg name="auth_req_json" type="s" direction="in"/>
        <arg name="result" type="s" direction="out"/>
    </method>
</interface>
</node>

创建接口并连接到接口信号后;

com::blah::Xyz interface = new com::blah::Xyz("com.blah.XYZ", "/com/blah/XYZ", QDBusConnection::systemBus(), this);
connect(interface , &com::blah::Xyz::Event, this, &SomeClass::HandleEvents)

当通过 dbus通过命令行从Xyz发送信号时,我无法在函数 SomeClass :: HandleEvents 中触发断点-发送

dbus-send --system --type=signal /com/blah/Xyz com.blah.XYZ.Event string:"hello"

使用 dbus-monitor --system ,我可以看到信号正在正确发出。

然后,在单元测试中,我创建了一个测试信号为;

QDBusMessage xyz_signal = QDBusMessage::createSignal(
    "/com/blah/XYZ", "com.blah.XYZ", "Event");
xyz_signal << "hello";
ASSERT_TRUE(connection.send(xyz_signal ));

那也未能触发断点。

经过数小时的寻找解决方案后,我放弃并创建了一些虚假的python dbus服务,该服务在命令中发出了Event信号(已替换dbus-send)并发出警告。.断点​​被触发,信号被捕获! (不是对QT dbus代码的单一更改)

我能够接收从python代码发出的信号,这一事实使我认为我的 dbus-send --system --type = signal 格式错误,但似乎无法修复。

这是python代码;

import gobject

import dbus
import dbus.service
import dbus.mainloop.glib


class XyzService(dbus.service.Object):

    @dbus.service.method("com.blah.Xyz",
                        in_signature='s', out_signature='s')
    def AuthenticateUser(self, auth_req_json):
        print (str("hello_message"))
        return '''
                {
                    "AuthenticationResponce" : "SUCCESS"
                }
                '''

    @dbus.service.method("com.blah.Xyz",
                        in_signature='s')
    def EmitEvent(self, str):
        self.Event(str)

    @dbus.service.signal('com.blah.Xyz', signature='s')
    def Event(self, event_json):
        # The signal is emitted when this method exits
        # You can have code here if you wish
        pass


if __name__ == '__main__':
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    system_bus = dbus.SystemBus()
    name = dbus.service.BusName("com.blah.Xyz", system_bus)
    object = XyzService(system_bus, '/com/blah/Xyz')

    mainloop = gobject.MainLoop()
    print "Running example service."
    mainloop.run()

更新

我刚刚发现,如果我使用空字符串创建路径和名称的接口,那么我将能够接收命令行 dbus-send 发送的信号

com::blah::Xyz interface = new com::blah::Xyz("", "", QDBusConnection::systemBus(), this);

上面的单元测试也通过了。

但是现在我无法调用方法 AuthenticateUser !这很令人困惑

更新2

我能够通过QT提供的RemoteControlledCar dbus示例重现此问题;该示例在此处找到; https://code.qt.io/cgit/qt/qtbase.git/tree/examples/dbus/remotecontrolledcar?h=5.10

在controller.cpp的构造函数中,我添加了以下内容;

Controller::Controller(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    car = new org::example::Examples::CarInterface("org.example.CarExample", "/Car",
                           QDBusConnection::sessionBus(), this);

    // added signal listener
    connect(car, &org::example::Examples::CarInterface::crashed,this,[](){qDebug("hello signal");});
    startTimer(1000);
}

当使用dbus-send触发信号时,消息hello信号不会被打印。但是,当我将服务路径和名称更改为空字符串时,便可以成功接收到信号;

car = new org::example::Examples::CarInterface("", "",
                       QDBusConnection::sessionBus(), this);

从命令行

dbus-send --session --type=signal /Car org.example.Examples.CarInterface.crashed

干杯, 西蒙

0 个答案:

没有答案