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
Forum Updated to NodeBB v4.3 + New Features

PyQt6 QtDBus How to Create Method Call

Scheduled Pinned Locked Moved Unsolved Qt for Python
2 Posts 1 Posters 483 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