PyQt6 QtDBus How to Create Method Call
-
I cannot seem to successfully create a method call to the D-Bus on Linux. Here's some code:
class DBusAdaptor(QDBusAbstractAdaptor): pyqtClassInfo('D-Bus Interface', 'org.pyqt.LinuxCleaner') pyqtClassInfo('D-Bus Path', '/LinuxCleaner') def __init__(self, parent): super().__init__(parent) connect = QDBusConnection.connectToBus(QDBusConnection.BusType.SessionBus, 'LinuxCleaner') conn_iface = connect.interface() if not connect.registerService('org.pyqt.LinuxCleaner'): print('Failed to register service') if not connect.registerObject('/LinuxCleaner', self): print('Failed to register Object!') print(connect.baseService()) self._check_polkit_privilege(conn_iface, 'org.pyqt.LinuxCleaner') def _check_polkit_privilege(self, conn_iface, service): """ :param conn_iface: D-Bus connection interface. :type conn_iface: QDBusConnectionInterface :param service: D-Bus service name. :type service: str :return: """ pid = conn_iface.servicePid(service).value() interface = QDBusInterface('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority', 'org.freedesktop.PolicyKit1.Authority', QDBusConnection.systemBus()) struct = QDBusArgument() struct.beginStructure() struct.add('unix-process', 10) struct.beginMap(10, 3) struct.beginMapEntry() struct.add('pid', 10) struct.add(pid, 3) struct.endMapEntry() struct.beginMapEntry() struct.add('start-time', 10) struct.add(0, 3) struct.endMapEntry() struct.endMap() struct.endStructure() struct.add('org.pyqt.LinuxCleaner.auth', 10) struct.beginMap(10, 10) struct.beginMapEntry() struct.add('AllowUserInteraction', 10) struct.add('true', 10) struct.endMapEntry() struct.endMap() struct.add(1, 3) struct.add('', 10) reply = interface.call('CheckAuthorization', struct) print(reply.errorMessage())
"CheckAuthorization" requires:
IN: (string {string: uint32, string: uint64}) IN: string IN: {string: string} IN: uint32 IN: string
The result (error message) is
Type of message, “((sa{su}))”, does not match expected type “((sa{sv})sa{ss}us)”
. After digging for a day,{sv}
means{string:variant}
, and the Qt variant to pass is aQDBusVariant
. This is my problem.beginMap()
requires twoQMetaType
's andQDBusVariant
is not a registered meta type. How would I pass aQDBusVariant
tobeginMap()
? I also tried another way:message = QDBusMessage.createMethodCall(interface.service(), interface.path(), interface.interface(), 'CheckAuthorization') pid = pid + (1 << 32) st = 0 + (1 << 64) message << 'unix-process' message << 'pid' << pid reply = QDBusConnection.systemBus().call(message)
Bear with that code, as its early in troubleshooting as it took me nowhere. That returns
(ssx)
. With that way, I can't figure out how to create a structure and dictionary (map) or array to send to the 'call()`.Any ideas how to solve this with either approach? I've tried 16 hours worth of things, and none of them allow me to successfully call the method "CheckAuthorization". Most things I try end up with a Marshalling error, saying a PyQt_PyObject is not registered with QtDBus.
-
I had posted this on StackOverflow back in July as well, and I received an answer today. I'll just link to the answer, which I haven't tested because I am in the middle of a different project. There are a couple good comments as well, so a link would be more prudent, I believe.