On Mon, 6 Aug 2012 13:59:08 -0400, Evade Flow <evadef...@gmail.com> wrote: > On Mon, Aug 6, 2012 at 1:03 PM, Phil Thompson > <p...@riverbankcomputing.com> wrote: >> On Mon, 6 Aug 2012 12:49:21 -0400, Evade Flow <evadef...@gmail.com> >> wrote: >>> On Mon, Aug 6, 2012 at 12:29 PM, Phil Thompson >>> <p...@riverbankcomputing.com> wrote: >>>> On Mon, 6 Aug 2012 12:15:44 -0400, Evade Flow <evadef...@gmail.com> >>>> wrote: >>>>> I'm trying to write a PyQt4-based mock object for a C++ app exposed >> over >>>>> D-Bus with the following interface: >>>>> >>>>> Q_CLASSINFO("D-Bus Interface", "com.acme.Audio.Control") >>>>> Q_CLASSINFO("D-Bus Introspection", >>>>> ' <interface name="com.acme.Audio.Control">\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="setParams">\n' >>>>> ' <arg direction="out" type="(i)" name="error"/>\n' >>>>> ' <arg direction="in" type="a(iiiii)" >>>>> name="audioSourceParameter"/>\n' >>>>> ' <annotation value="QVector<AudioSourceParameters>" >>>>> name="com.trolltech.QtDBus.QtTypeName.In0"/>\n' >>>>> ' <annotation value="Errors::ErrorCode" >>>>> name="com.trolltech.QtDBus.QtTypeName.Out0"/>\n' >>>>> ' </method>\n' >>>>> ' </interface>\n') >>>>> >>>>> It's unclear to me how how the setParams() function should be >> decorated. >>>>> For the echo() function, I have: >>>>> >>>>> @pyqtSlot(str, result=str) >>>>> def echo(self, phrase): >>>>> return self.parent().echo(phrase) >>>>> >>>>> But what should I put for setParams()? I was tempted to write: >>>>> >>>>> @pyqtSlot('a(iiiii)', result='(i)') >>>>> def setParams(self, volume): >>>>> return self.parent().echo(phrase) >>>>> >>>>> But this results in: >>>>> >>>>> TypeError: C++ type 'a(iiiii)' is not supported as a pyqtSlot type >>>>> argument type >>>>> >>>>> So... how does one expose a function to D-Bus that accepts an array of >>>>> structs, each containing 5 ints? >>>> >>>> What would be the C++ signature? Try that as a string. >>>> >>>> Phil >>> >>> The C++ signature is: >>> >>> void setParams(QList<AudioSourceParameters> audioSourceParameters, >>> Errors::ErrorCode &error); >>> >>> where AudioSourceParameters is defined as: >>> >>> struct AudioSourceParameters >>> { >>> int volume; >>> int balance; >>> int fader; >>> int fadein; >>> int fadeout; >>> }; >>> >>> The C++ code sets things up with: >>> >>> Q_DECLARE_METATYPE(QList<AudioSourceParameters>); >>> >>> and: >>> >>> qDBusRegisterMetaType<AudioSourceParameters>(); >>> qDBusRegisterMetaType<QList<AudioSourceParameters> >(); >>> >>> The introspection XML (presumably output by qdbuscpp2xml) shows this as >>> 'a(iiiii)'. That's what the client app (the one I'm trying to provide a >>> mock server for) is expecting to see. >>> >>> Any ideas how to make this work with PyQt? >> >> You probably can't using the QtDBus module because PyQt doesn't know >> anything about AudioSourceParameters. >> >> You should be able to use the standard Python dbus module which will >> bypass the Qt conversions. >> >> Phil > > What clients expect is 'a(iiiii)', so the convenience type declared in > the C++ server I'm trying to mock out shouldn't matter for my purposes > (should it?) > > It makes sense that PyQt wouldn't know anything about > 'AudioSourceParameters', but can it handle 'a(iiiii)'? Or are D-Bus > arrays and structs (and arrays-of-structs) not supported? > > I've seen a few PyQt code examples that use QDBusArgument to marshal > arbitrary arguments, but I haven't seen any examples where complex > objects are demarshalled. > > This seems fine: > > @pyqtSlot('QList<int>') > def func(self, args): > pass
Because QList<int> is explicitly supported by PyQt. > but this: > > @pyqtSlot('QList<QList<int> >') > def func(self, args): > pass > > results in: > > File "fake_hifi_audio.py", line 44, in HifiAudioServerAdaptor > @pyqtSlot('QList<QList<int> >') > TypeError: C++ type 'QList<QList<int> >' is not supported as a > pyqtSlot type argument type Because QList<QList<int> > isn't supported. > If arrays of structs aren't supported, is there some way I can get the > thing that clients send as 'a(iiiii)' into a QDBusArgument variable and > demarshal it manually? PyQt's DBus bindings are *so* much better than > the standard python dbus module that I shudder at the thought of having > to go back to it... `:-} In theory you should be able to use QDBusArgument but I've not tested it - I've always struggled to find test cases. Phil _______________________________________________ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt