如何在 PyQt5 中将字符串数组传递给 dbus? [复制]

Posted

技术标签:

【中文标题】如何在 PyQt5 中将字符串数组传递给 dbus? [复制]【英文标题】:How to pass an array of string to dbus in PyQt5? [duplicate] 【发布时间】:2015-03-20 11:02:56 【问题描述】:

我正在尝试使用 python3.4 和 pyqt5.4 对 java 编写的守护进程进行 dbus 调用,我正在调用的方法的守护进程的签名是 asasv

我正在打的电话是

fpiudaemon = QDBusInterface("it.libersoft.FirmapiuDInterface", "/it/libersoft/FirmapiuD", interface='it.libersoft.FirmapiuDInterface' , parent=None)
result = fpiudaemon.call('sign',filepath,options)

在哪里

print (filepath) -> ['/home/svalo/programmi/devel/pythondeps']
print (options) -> 'pin': '12345678', 'outdir': '/home/svalo/programmi/devel/firmapiu-gui'

print(type(filepath)) -> <class 'list'>
print(type(options)) -> <class 'dict'>

但是,当我监控 dbus 时,我得到的是

方法调用 sender=:1.242 -> dest=it.libersoft.FirmapiuDInterface serial=67 path=/it/libersoft/FirmapiuD;接口=it.libersoft.FirmapiuDInterface;成员=签名
   大批 [
      变体字符串“/home/svalo/programmi/devel/firmapiu-gui/pythondeps”
   ]
   大批 [
      字典条目(
         字符串“outdir”
         变体字符串“/home/svalo/programmi/devel/firmapiu-gui”
      )
      字典条目(
         字符串“针”
         变体字符串“12345678”
      )
   ]

我想得到的是

方法调用 sender=:1.242 -> dest=it.libersoft.FirmapiuDInterface serial=67 path=/it/libersoft/FirmapiuD;接口=it.libersoft.FirmapiuDInterface;成员=签名
   大批 [
      字符串“/home/svalo/programmi/devel/libersoft/firmapiu-gui/pythondeps”
   ]
   大批 [
      字典条目(
         字符串“outdir”
         变体字符串“/home/svalo/programmi/devel/libersoft/firmapiu-gui”
      )
      字典条目(
         字符串“针”
         变体字符串“12345678”
      )
   ]

也就是说,我希望 python 发送一个字符串数组,而不是它发送一个包含字符串的变量数组。

daemon devel 用 java 编写了一个简单的客户端,它可以根据签名工作

我在这里错过了什么?

【问题讨论】:

【参考方案1】:

根据dbus-spec,string-type定义如下:

STRING 115 (ASCII 's') UTF-8 字符串(必须是有效的 UTF-8)。必须以 nul 结尾且不包含其他 nul 字节。

这似乎暗示您应该传递一个 UTF-8 编码的 bytes 对象,而不是 unicode 对象。

编辑

您可能需要将其作为QByteArray 传递:

QtCore.QByteArray(unicode_string.encode('utf-8'))

【讨论】:

好的,我尝试arrfoo = bytearray('string', 'utf-8') 并使用arrfoo 而不是文件路径作为参数调用结果,但它给出了Marshalling failed: Unregistered type PyQt_PyObject passed in arguments 甚至没有进入dbus @svalo。您可能需要使用QByteArray(请参阅我更新的答案)。我自己无法测试,所以很抱歉猜测。 PyQt 没有自动处理这似乎很奇怪 - 也许某处有错误? 好的,谢谢。我试过 foo='test',test=QByteArray(foo.encode('utf-8')),print(type(test)) -&gt; &lt;class 'PyQt5.QtCore.QByteArray'&gt; ,用 result = self.fpiudaemon.call('sign', [test], options) 调用它会得到 Interface; member=sign array [ variant array of bytes "test"] ,所以又不是字符串数组 @svalo。嗯,我的直觉是它要么是一个错误,要么是一个非常非常不直观的 API。从您的原始示例中,很明显 PyQt 能够创建非变体字符串,因为它们用于 dict 条目键。它似乎只是数组 elements 和 dict 条目 values 被转换为变体。我想知道容器外的字符串值是否也转换为变体?如果不是,它似乎强烈暗示了某种错误(或错误功能)。 我成功地将字符串发送到容器外,dbus 将其视为字符串而不是变体字符串,所以,是的,也许你是对的。我会问 PyQt 人【参考方案2】:

5年后,答案出现了!

您可以使用QDbusArgument 指定 dbus 参数的类型签名。这是一个例子:

filepath = QDBusArgument()
filepath.add(['/home/svalo/programmi/devel/pythondeps'], QMetaType.QStringList)
result = fpiudaemon.call('sign',filepath,options)

显然要确保你的数据可以直接转换成你指定的类型。

【讨论】:

不要在多个帖子中发布相同的答案,如果您有权限,则应将问题标记为重复。 我想我不会。这个问题是我对这个问题的查询在 Google 上的唯一结果,所以我想确保其他任何登陆这里的人都能得到答案。 好吧,为此,您回答自己的问题就足够了,因为其他人会以与您找到此问题相同的方式找到您的答案。

以上是关于如何在 PyQt5 中将字符串数组传递给 dbus? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在python中将dbus.Array从at解码为十六进制或字符串

PyQt 5.6:连接到 DBus 信号挂起

如何在 Laravel 中将多个数组/变量传递给 DOMPDF?

在另一个 Activity 中将字符串(或数组)传递给 ListView(NPE 错误)

如何在 PyQt5 中将字节数组图像添加到 QLabel

如何在反应中将子组件的状态数组传递给父组件?