[PyQt] How to expose function accepting array of struct to D-Bus?

Phil Thompson phil at riverbankcomputing.com
Mon Aug 6 18:03:20 BST 2012


On Mon, 6 Aug 2012 12:49:21 -0400, Evade Flow <evadeflow at gmail.com> wrote:
> On Mon, Aug 6, 2012 at 12:29 PM, Phil Thompson
> <phil at riverbankcomputing.com> wrote:
>> On Mon, 6 Aug 2012 12:15:44 -0400, Evade Flow <evadeflow at 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


More information about the PyQt mailing list