Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PyQt6 QtDBus How to Create Method Call
Qt 6.11 is out! See what's new in the release blog

PyQt6 QtDBus How to Create Method Call

Scheduled Pinned Locked Moved Unsolved Qt for Python
2 Posts 1 Posters 829 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • MalonnM Offline
    MalonnM Offline
    Malonn
    wrote on last edited by
    #1

    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 a QDBusVariant. This is my problem. beginMap() requires two QMetaType's and QDBusVariant is not a registered meta type. How would I pass a QDBusVariant to beginMap()? 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.

    1 Reply Last reply
    0
    • MalonnM Offline
      MalonnM Offline
      Malonn
      wrote on last edited by
      #2

      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.

      StackOverflow

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved