How to get QDBusConnection::connect() failure reason

3.5k Views Asked by At

I'm trying to connect to a D-Bus signal this way:

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

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

QDBusConnection::connect() returns a boolean, how do I get extended error information? If a check QDBusConnection::lastError() it returns no useful information (as QDBusError::isValid() is false).

2

There are 2 best solutions below

0
NexD. On BEST ANSWER

I had the same issue and it turned out that the slot I connected to had the wrong parameter types. They must match according to Qt's documentation and it looks like connect() verifies that, despite not explicitly mentioned.

Warning: The signal will only be delivered to the slot if the parameters match.

I suggest d-feet to list signals and check their parameter types. dbus-monitor does list signals, paths and such too, but not always the exact type of parameters.


One important observation though: I fixed the issue in my particular case by using different slot parameters than the actual signal has!

I wanted to connect to a com.ubuntu.Upstart0_6 signal mentioned here to detect when the screen in Ubuntu is locked/unlocked. dbusmonitor prints the following and d-feet shows parameters (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 [
   ]

Hence the signal should be of type

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

This however made connect() return false. The solution was to remove the array parameter from the slot:

void screenLockChangedUbuntu(QString event) // works

I am aware that the array parameter was always empty, but I cannot explain why it only worked when removing it.

3
talamaki On

You could try these tricks:

1) Set QDBUS_DEBUG environment variable before running your application.

export QDBUS_DEBUG=1

2) Start dbus-monitor to see what's happening on the bus. You may need to set a global policy to be able to eavesdrop system bus depending on your distro.

Update:

Are you sure connecting to the system bus succeeded? If it fails you should probably check system.conf policy and possibly create own conf in system.d. This post might be helpful.

You could first connect to the system bus with QDBusConnection::connectToBus and check if it succeeded with QDBusConnection::isConnected. Only after that you try to connect to the signal and check if that succeeded.

QDBusConnection bus = QDBusConnection::connectToBus(QDBusConnection::systemBus, myConnectionName);
if (bus.isConnected())
{
    if(!bus.connect( ... ))
    {
        // Connecting to signal failed
    }
}
else
{
    // Connecting to system bus failed
}