PyQt5 dbus: Force type signature of signal argument to be array of string

江枫思渺然 提交于 2020-01-11 14:14:08

问题


I'm writing an MPRIS player, which communicates with clients over dbus. I need to emit a signal when my playback state changes. However, the signal requires a format of (sa{sv}as), and my code is producing (sa{sv}av). Here's the important part:

self.signal = QDBusMessage.createSignal(
   "/org/mpris/MediaPlayer2",
   "org.freedesktop.DBus.Properties",
   "PropertiesChanged"
)
self.signal.setArguments(
    [interface, {property: values}, ['']]
)

The problem is the third item in the list given to setArguments. It is an empty string in a list because I need to produce a type of 'array of string' (as) but pyqt5 translates that into 'array of variant' (av).

I never need to put any actual data in that list, I just need the type signature to be correct.

Is there any way to do this in PyQt5? Perhaps using QDBusArgument?


回答1:


I... I got it working. Wow. That was a campaign.

I don't know what is going wrong exactly, I wasn't able to dig out of the PyQt5 source where exactly the conversion happens. However, I did look into QDbusArgument(). There is no documentation for this in python, and the C++ docs are worthless due to major differences, so I took to the source code. in sip/QtDbus/qdbusargument.sip, I discovered a completely undocumented new method called qdbusargument_add. This maps to QDbusArgument().add() in python. It is used to add arguments with an explicit type id to a QDbusArgument. And it has a special case for QStringList!

From then I just bruteforced every possibility I could think of with arguments to QDbusArgument(), and finally got the following:

def PropertiesChanged(self, interface, property, values):
    """Sends PropertiesChanged signal through sessionBus.
    Args:
        interface: interface name
        property: property name
        values: current property value(s)
    """
    emptyStringListArg = QDBusArgument()
    emptyStringListArg.add([""], QMetaType.QStringList)
    self.signal.setArguments([interface, {property: values}, emptyStringListArg])
    QDBusConnection.sessionBus().send(self.signal)

It'd be great if the add() function could be documented, but I can't seem to send messages to the PyQt5 mailing list. Do I have to register first?



来源:https://stackoverflow.com/questions/59587057/pyqt5-dbus-force-type-signature-of-signal-argument-to-be-array-of-string

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!