dbus-python, in case you don't know

Mon 29 November 2010
  • 手艺 tags:
  • dbus
  • linux
  • python published: true comments: true

上周用dbus-python写exaile插件,实现mpris2.0,非常痛苦,因为几乎没有完整的文档,只有一个tutorials帮助你入门。总结一下我这次quick and dirty的开发所掌握的资料,当然,因为没有太多时间,所以也没有对dbus做更深入的了解,仅仅是in case you don't know。

DBus Interface Properties

对mpris 2.0中定义的properties用dbus-python应该如何实现呢,似乎没有@dbus.service.properties这种decorator啊。这里的文档对Properties进行了简单的说明,对于python程序,只能这样实现了:
[cc lang="python"]
@dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v')
def Get(self, interface, prop):
...
@dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='ssv')
def Set(self, interface, prop, value):
...
@dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}')
def GetAll(self, interface):
...
[/cc]
程序里通过prop判断property名字,返回结果。没办法,就是这样。

指定返回数据的dbus类型

对于dbus接口返回的variant类型,dbus-python会guess_signature。可是这部分的功能有的时候并不如我们想象,比如返回一个dict类型,其中的value有字符串有list有int,而out_signature是v。这种情况在Property Get的时候非常常见,如果不能手动指定类型,guess_signature得到的结果,value是统一类型,即,int会报错,如果没有int类型,会将所有字符串转成list(dbus的array)

这种情况需要手动指定返回的类型,用dbus.types模块下的类型对python显示包装,对dict类型,需要用dbus.types.Dictionary()包装,并且在构造函数里传入signature='sv‘及相应的variant_level即可显示告知类型。同样,对list对象,需要用dbus.types.Array()包装。

这样即可绕过guest_signature,如果用dbus-monitor查看,就可以看到类型为variant string了。