On Tue, 7 Aug 2012 15:45:43 -0400, Evade Flow <evadef...@gmail.com> wrote: >> In theory you should be able to use QDBusArgument but I've not tested >> it - I've always struggled to find test cases. > > Maybe the little server app appended below will help. Using dbus-send, I > can exercise the 'name' property and 'echo' method, as well as the > introspection interface: > > # Call 'echo' method > dbus-send --print-reply --dest=com.example.dbus /com/example/dbus \ > com.example.dbus.echo string:Hello > > # Exercise introspection interface > dbus-send --print-reply --dest=com.example.dbus /com/example/dbus \ > org.freedesktop.DBus.Introspectable.Introspect > > # Get the 'name' property > dbus-send --print-reply --dest=com.example.dbus /com/example/dbus \ > org.freedesktop.DBus.Properties.Get string:com.example.dbus > string:name > > # Set 'name' > dbus-send --print-reply --dest=com.example.dbus /com/example/dbus \ > org.freedesktop.DBus.Properties.Set string:com.example.dbus \ > string:name variant:string:MyNewName > > # Call 'setPosition' method > dbus-send --print-reply --dest=com.example.dbus /com/example/dbus \ > com.example.dbus.setPosition double:1.0 double:2.0 double:3.0 > > Unfortunately for me, attempts to call setPosition() result in: > > Error org.freedesktop.DBus.Error.UnknownMethod: No such method > 'setPosition' in interface 'com.example.dbus' at object path > '/com/example/dbus' (signature 'ddd') > > I suppose this makes sense, but I was hoping there might be a > workaround. It would be really great to be able to write a PyQt-based > implementation of *any* D-Bus specification. That way, I could mock out > any arbitrary server's functionality for testing. > > For now, it looks like structs aren't supported? I'd be willing to help > add that support if it seems doable, but I'm not sure where to start, or > what the effort level might be. (I can probably spend about 20 hours on > it without getting into too much trouble...) > > ---------- > > from PyQt4 import QtDBus > from PyQt4.QtCore import (QCoreApplication, QObject, Q_CLASSINFO, pyqtSlot, > pyqtProperty) > from PyQt4.QtDBus import QDBusArgument, QDBusConnection, > QDBusAbstractAdaptor > > class MyServer(QObject): > > def __init__(self): > QObject.__init__(self) > self.__dbusAdaptor = ServerAdaptor(self) > self.__name = 'myname' > > def echo(self, value): > return'Received: {0}'.format(value) > > @property > def name(self): > return self.__name > > @name.setter > def name(self, value): > self.__name = value > > > class ServerAdaptor(QDBusAbstractAdaptor): > Q_CLASSINFO("D-Bus Interface", "com.example.dbus") > Q_CLASSINFO("D-Bus Introspection", > ' <interface name="com.example.dbus">\n' > ' <property name="name" type="s" access="readwrite"/>\n' > ' <method name="echo">\n' > ' <arg direction="in" type="s" name="phrase"/>\n' > ' <arg direction="out" type="s" name="echoed"/>\n' > ' </method>\n' > ' <method name="setPosition">\n' > ' <arg direction="in" type="(ddd)" name="pos"/>\n' > ' </method>\n' > ' </interface>\n') > > def __init__(self, parent): > super().__init__(parent) > > @pyqtSlot(str, result=str) > def echo(self, phrase): > return self.parent().echo(phrase) > > @pyqtSlot(QDBusArgument) > def setPosition(self, pos): > print("How can I call this function?") > > > @pyqtProperty(str) > def name(self): > return self.parent().name > > @name.setter > def name(self, value): > self.parent().name = value > > def start(): > app = QCoreApplication([]) > bus = QDBusConnection.sessionBus() > server = MyServer() > bus.registerObject('/com/example/dbus', server) > bus.registerService('com.example.dbus') > app.exec() > > if __name__ == '__main__': > start()
It seems the trick is to specify QDBusMessage as the slot argument and use its arguments() method to get at the actual arguments. For example, if you have a method setColors() that takes a single argument that is an array of structs of three ints (i.e. an array of RGB values). This would have a DBus signature of "a(iii)". The Python implementation would be... @pyqtSlot(QDBusMessage) def setColors(self, msg): for red, green, blue in msg.arguments()[0]: print(red, green, blue) Does this technique solve all your issues? I'll update the docs. Phil _______________________________________________ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt