简体   繁体   English

如何从 Python 向 dBus 发送无符号值

[英]How to send unsigned values to dBus from Python

I'm trying to use PyQt5's DBus module to interact with the KDE PowerManagerAgent.我正在尝试使用 PyQt5 的 DBus 模块与 KDE PowerManagerAgent 进行交互。 When calling the AddInhibition method I need to send the first paramter as an uint32 (Unsigned int), but the code sends the value as a singed int.调用 AddInhibition 方法时,我需要将第一个参数作为 uint32(无符号整数)发送,但代码将值作为单整数发送。

The code is written using Python 3代码是使用 Python 3 编写的

self.dBus = QtDBus.QDBusConnection.sessionBus()
msg = QtDBus.QDBusMessage.createMethodCall(self.dBusService, self.dBusPath,self.dBusInterface,'AddInhibition')
msg << 1 << who << reason
reply = QtDBus.QDBusReply(self.dBus.call(msg))

Looking at the output from dbus-monitor I can tell that the code does indeed contact the powermonitor but fails to find the correct AddInhibition method due to the first parameter being type as int32查看 dbus-monitor 的输出,我可以看出代码确实与 powermonitor 联系,但由于第一个参数类型为 int32,因此无法找到正确的 AddInhibition 方法

Output from dbus-monitor when trying to call AddInhibition尝试调用 AddInhibition 时 dbus-monitor 的输出

Call称呼

method call time=1549706946.073218 sender=:1.172 -> destination=org.kde.Solid.PowerManagement.PolicyAgent serial=5 path=/org/kde/Solid/PowerManagement/PolicyAgent;方法调用时间=1549706946.073218 sender=:1.172 -> destination=org.kde.Solid.PowerManagement.PolicyAgent serial=5 path=/org/kde/Solid/PowerManagement/PolicyAgent; interface=org.kde.Solid.PowerManagement.PolicyAgent; interface=org.kde.Solid.PowerManagement.PolicyAgent; member=AddInhibition int32 1 string "This" string "fails" member=AddInhibition int32 1字符串“这个”字符串“失败”

Reply回复

error time=1549706946.073536 sender=:1.29 -> destination=:1.172 error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=5 string "No such method 'AddInhibition' in interface 'org.kde.Solid.PowerManagement.PolicyAgent' at object path '/org/kde/Solid/PowerManagement/PolicyAgent' (signature 'iss')"错误时间=1549706946.073536 sender=:1.29 -> destination=:1.172 error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=5 字符串“在接口'org.kde.Solid.PowerManagement'atPolicyA中没有这样的方法'AddInhibition'对象路径'/org/kde/Solid/PowerManagement/PolicyAgent'(签名'iss')”

Output from dbus-monitor when using QDBusViewer application使用 QDBusViewer 应用程序时 dbus-monitor 的输出

Call称呼

method call time=1549723045.320128 sender=:1.82 -> destination=org.kde.Solid.PowerManagement.PolicyAgent serial=177 path=/org/kde/Solid/PowerManagement/PolicyAgent;方法调用时间=1549723045.320128 sender=:1.82 -> destination=org.kde.Solid.PowerManagement.PolicyAgent serial=177 path=/org/kde/Solid/PowerManagement/PolicyAgent; interface=org.kde.Solid.PowerManagement.PolicyAgent; interface=org.kde.Solid.PowerManagement.PolicyAgent; member=AddInhibition uint32 1 string "This" string "Works" member=AddInhibition uint32 1字符串“这个”字符串“作品”

Reply回复

method return time=1549723045.320888 sender=:1.29 -> destination=:1.82 serial=1370 reply_serial=177 uint32 30方法返回时间=1549723045.320888 sender=:1.29 -> destination=:1.82 serial=1370 reply_serial=177 uint32 30

Since Python is not strongly typed how do I specify the the parameter must be typed as an unsigned int?由于 Python 不是强类型,我如何指定参数必须输入为无符号整数?

You can use the DBusArgument class to do this by specifying the QMetaType of the argument.您可以使用DBusArgument类通过指定参数的QMetaType来执行此操作。

For example, say you want to use the RequestName method from org.freedesktop.DBus (see the spec ).例如,假设您想使用org.freedesktop.DBusRequestName方法(请参阅规范)。 The flags argument is an unsigned int, so you'll run into this problem: flags参数是一个无符号整数,所以你会遇到这个问题:

>>> from PyQt5.QtDBus import QDBusConnection, QDBusInterface
>>> sessionbus = QDBusConnection.sessionBus()
>>> iface = QDBusInterface("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", sessionbus)
>>> c = iface.call('RequestName', 'com.mydomain.myapp', 4)
>>> c.arguments()
['Call to RequestName has wrong args (si, expected su)\n']

So, it's saying it got a string and an integer ( si ), but it wanted a string and an unsigned integer ( su ).所以,它说它有一个字符串和一个整数( si ),但它想要一个字符串和一个无符号整数( su )。 So, we'll use the QDBusArgument class and specify QMetaType.UInt :因此,我们将使用QDBusArgument类并指定QMetaType.UInt

>>> from PyQt5.QtCore import QMetaType
>>> from PyQt5.QtDBus import QDBusConnection, QDBusInterface, QDBusArgument
>>> sessionbus = QDBusConnection.sessionBus()
>>> iface = QDBusInterface("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", sessionbus)
>>> a1 = QDBusArgument()
>>> a1.add('com.mydomain.myapp', QMetaType.QString)
>>> a2 = QDBusArgument(4, QMetaType.UInt)
>>> c = iface.call('RequestName', a1, a2)
>>> c.arguments()
[1]

Since the string was fine, that didn't have to be a QDBusArgument .由于字符串很好,因此不必是QDBusArgument I just wanted to show the two ways of constructing it (with the .add() method and just using the constructor).我只是想展示构建它的两种方法(使用.add()方法和只使用构造函数)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM