如何从Python将无符号值发送到dBus

时间:2019-02-09 14:42:24

标签: python qt5 dbus qtdbus

我正在尝试使用PyQt5的DBus模块与KDE PowerManagerAgent进行交互。调用AddInhibition方法时,我需要将第一个参数作为uint32(无符号整数)发送,但是代码将值作为单精度整数发送。

代码是使用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))

查看dbus-monitor的输出,我可以知道代码确实确实与powermonitor联系,但是由于第一个参数的类型为int32,所以未能找到正确的AddInhibition方法

尝试调用AddInhibition时dbus-monitor的输出

致电

方法调用时间= 1549706946.073218发送者=:1.172-> destination = org.kde.Solid.PowerManagement.PolicyAgent serial = 5 path = / org / kde / Solid / PowerManagement / PolicyAgent; interface = org.kde.Solid.PowerManagement.PolicyAgent;成员= AddInhibition     int32 1    字符串“ This”    字符串“失败”

回复

错误时间= 1549706946.073536发件人=:1.29->目的地=:1.172 error_name = org.freedesktop.DBus.Error.UnknownMethodreply_serial = 5    字符串“对象路径“ / org / kde / Solid / PowerManagement / PolicyAgent”(签名“ iss”)上的接口“ org.kde.Solid.PowerManagement.PolicyAgent”中没有这样的方法“ AddInhibition””

使用QDBusViewer应用程序时dbus-monitor的输出

致电

方法调用时间= 1549723045.320128发送者=:1.82-> destination = org.kde.Solid.PowerManagement.PolicyAgent serial = 177 path = / org / kde / Solid / PowerManagement / PolicyAgent; interface = org.kde.Solid.PowerManagement.PolicyAgent;成员= AddInhibition     uint32 1    字符串“ This”    字符串“ Works”

回复

方法返回时间= 1549723045.320888发送者=:1.29->目的地=:1.82串行= 1370 Reply_serial = 177    uint32 30

由于Python的类型不是强类型,我如何指定必须以无符号int类型输入参数?

1 个答案:

答案 0 :(得分:0)

您可以通过指定参数DBusArgument来使用QMetaType类。

例如,假设您要使用RequestName中的org.freedesktop.DBus方法(请参见the spec)。 flags参数是一个无符号的int,因此您将遇到此问题:

>>> 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']

因此,它说它有一个字符串和一个整数(si),但它需要一个字符串和一个无符号整数(su)。因此,我们将使用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]

由于字符串很好,所以不必使用QDBusArgument。我只是想展示构造它的两种方式(使用.add()方法并仅使用构造函数)。