QtDBus slot not working with expected prototype
-
Hello all,
To keep it simple, I am trying to communicate with bluez using the QtDBus library. Specifically, I'm trying to connect to the InterfacesAdded signal part of org.freedesktop.DBus.ObjectManager.
The dbus signal has the following prototype:
Object Path, Dict of {String, Dict of {String, Variant}}.
From my understanding, the Qt-equivalent of this would be:
QDBusObjectPath, QMap<QString, QVariantMap>
So I have my slot:
typedef QMap<QString, QVariantMap> InterfaceList; Q_DECLARE_METATYPE(InterfaceList) void interfaces_added(const QDBusObjectPath &, InterfaceList);
And my my connection:
QDBusConnection::systemBus().connect("org.bluez", "/", "org.freedesktop.DBus.ObjectManager", "InterfacesAdded", this, SLOT(interfaces_added(const QDBusObjectPath &, InterfaceList)));
But the function doesn't get called on the signal.
What's interesting though is when I have my slot like this (with a matching connection):
void interfaces_added(const QDBusObjectPath &, QMap<QString, QVariant>);
my function gets called and I'm able to handle the signal (albeit haven't figured out how to get anything meaningful out of the QMap).
I'm not really sure what to make of this. I don't believe its an issue with dbus becuase when using dbus-monitor I see the data in the expected format. For what its worth, I am able to connect to the InterfacesRemoved signal without any issues.
Is Qt unable to handle more complex types like nested maps?
-
Hi and welcome to devnet,
Disclaimer: I haven't used that module yet.
Doesn't the QVariant parameter contain a QVariantMap ?
-
I tried printing out the data I was receiving, and this is an example of what I was getting (using the "incorrect" prototype):
QMap(("org.bluez.Device1", QVariant(void*, 0x65))("org.freedesktop.DBus.Introspectable", QVariant(void*, 0x0))("org.freedesktop.DBus.Properties", QVariant(void*, 0x0)))
For the most part, what I get makes sense, except for the
QVariant(void*, 0x65)
in the first entry. It doesn't seem to contain a QVariantMap. -
Do you know what data you should be receiving ?
-
Yeah instead of the QVariant I am expecting a QVariantMap (but the connection doesn't work with a slot with that kind of prototype).
Here is an example of the data that would be received
array [ dict entry( string "Address" variant string "FF:FF:FF:FF:FF:FF" ) dict entry( string "AddressType" variant string "random" ) dict entry( string "Name" variant string "device name" ) dict entry( string "Alias" variant string "device alias" ) dict entry( string "Paired" variant boolean false ) dict entry( string "Trusted" variant boolean false ) dict entry( string "Blocked" variant boolean false ) dict entry( string "LegacyPairing" variant boolean false ) dict entry( string "RSSI" variant int16 -69 ) dict entry( string "Connected" variant boolean false ) dict entry( string "UUIDs" variant array [ string "0000fea0-0000-1000-8000-00805f9b34fb" ] ) dict entry( string "Adapter" variant object path "/org/bluez/hci0" ) dict entry( string "ServiceData" variant array [ dict entry( string "00000000-0000-0000-0000-000000000000" variant array of bytes [ ff ff ff ff ff ff ff ff ff ff ff ff ff ] ) ] ) dict entry( string "ServicesResolved" variant boolean false ) ]
where
array
is essentially the Map. -
This question is a bit old now, but I ran into the same problem without finding a solution elsewhere, so maybe this will be useful for others to know.
I tried exactly the same code as you, and found the the same issue of the signal not connecting properly. What worked for me was to add the following somewhere in the code (e.g. the class constructor) to get executed before the
connect()
call.#include <QDBusMetaType> // Add to code (e.g. constructor) to be run before the connect() call qDBusRegisterMetaType<InterfaceList>();
The
connect()
call then returned true, the signal fired, and I was able to extract the object properties straight from theInterfaceList
object passed with the signal.