1

我正在尝试以这种方式连接到 D-Bus 信号:

bool result = QDBusConnection::systemBus().connect(
    "foo.bar",  // service
    "/foo/bar", // path 
    "foo.bar",  // interface
    "SignalSomething",
    this,
    SLOT(SignalSomethingSlot()));

if( !result )
{
    // Why!?
}

QDBusConnection::connect()返回一个布尔值,我如何获得扩展的错误信息?如果检查QDBusConnection::lastError()它不返回有用的信息(原样QDBusError::isValid()false

4

2 回答 2

2

我遇到了同样的问题,结果发现我连接的插槽的参数类型错误。它们必须根据 Qt 的文档进行匹配,并且看起来可以connect()验证这一点,尽管没有明确提及。

警告:只有参数匹配时,信号才会被传递到插槽。

我建议d-feet列出信号并检查它们的参数类型。dbus-monitor确实列出了信号、路径等,但并不总是列出确切的参数类型。


不过,一个重要的观察结果是:我在特定情况下通过使用与实际信号不同的插槽参数解决了这个问题!

我想连接到此处com.ubuntu.Upstart0_6提到的信号以检测 Ubuntu 中的屏幕何时被锁定/解锁。打印以下内容并显示参数dbusmonitord-feet(String, Array of [String])

// dbusmonitor output
signal time=1529077633.579984 sender=:1.0 -> destination=(null destination) serial=809 path=/com/ubuntu/Upstart; interface=com.ubuntu.Upstart0_6; member=EventEmitted
   string "desktop-unlock"
   array [
   ]

因此信号应该是类型

void screenLockChangedUbuntu(QString event, QVector<QString> args) // connect() -> false

然而这取得了connect()回报false。解决方案是从插槽中删除数组参数:

void screenLockChangedUbuntu(QString event) // works

我知道数组参数总是空的,但我无法解释为什么它只在删除它时才起作用。

于 2018-07-09T16:32:51.147 回答
0

你可以试试这些技巧:

1)在运行应用程序之前设置QDBUS_DEBUG环境变量。

export QDBUS_DEBUG=1

2) 启动dbus-monitor以查看总线上发生了什么。您可能需要设置全局策略才能根据您的发行版窃听系统总线。

更新:

您确定连接到系统总线成功了吗?如果失败,您可能应该检查system.conf策略并可能在system.d. 这篇文章可能会有所帮助。

您可以先使用QDBusConnection::connectToBus连接到系统总线,然后使用QDBusConnection::isConnected检查它是否成功。只有在那之后,您才尝试连接到信号并检查是否成功。

QDBusConnection bus = QDBusConnection::connectToBus(QDBusConnection::systemBus, myConnectionName);
if (bus.isConnected())
{
    if(!bus.connect( ... ))
    {
        // Connecting to signal failed
    }
}
else
{
    // Connecting to system bus failed
}
于 2016-05-18T19:09:32.933 回答