Как передать массив строк в dbus в PyQt5?

Я пытаюсь сделать вызов dbus, используя python3.4 и pyqt5.4, для демона, написанного на Java, подпись демона для метода, который я вызываю, asa{sv}

Звонок, который я делаю,

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, я получаю

method call sender=:1.242 -> dest=it.libersoft.FirmapiuDInterface serial=67 path=/it/libersoft/FirmapiuD; interface=it.libersoft.FirmapiuDInterface; member=sign
   array [
      variant          string "/home/svalo/programmi/devel/firmapiu-gui/pythondeps"
   ]
   array [
      dict entry(
         string "outdir"
         variant             string "/home/svalo/programmi/devel/firmapiu-gui"
      )
      dict entry(
         string "pin"
         variant             string "12345678"
      )
   ]

То, что я хотел бы получить, это

method call sender=:1.242 -> dest=it.libersoft.FirmapiuDInterface serial=67 path=/it/libersoft/FirmapiuD; interface=it.libersoft.FirmapiuDInterface; member=sign
   array [
      string "/home/svalo/programmi/devel/libersoft/firmapiu-gui/pythondeps"
   ]
   array [
      dict entry(
         string "outdir"
         variant             string "/home/svalo/programmi/devel/libersoft/firmapiu-gui"
      )
      dict entry(
         string "pin"
         variant             string "12345678"
      )
   ]

То есть я ожидаю, что python отправит массив строк, а вместо этого он отправит массив вариантов, содержащих строки.

Демон-разработчик написал простой клиент на java, и он работает с соблюдением подписи.

Что мне здесь не хватает?


person svalo    schedule 21.01.2015    source источник


Ответы (2)


Согласно dbus-spec, тип строки определяется следующим образом. :

STRING 115 (ASCII 's') Строка UTF-8 (должна быть действительной UTF-8). Должен завершаться нулем и не содержать других нулевых байтов.

Кажется, это означает, что вы должны передавать объект bytes в кодировке UTF-8, а не объект Unicode.

ИЗМЕНИТЬ:

Возможно, вам придется передать это как QByteArray:

QtCore.QByteArray(unicode_string.encode('utf-8'))
person ekhumoro    schedule 22.01.2015
comment
Хорошо, я попробовал arrfoo = bytearray('string', 'utf-8') и вызвал результат с arrfoo вместо пути к файлу в качестве аргумента, но это дает Marshalling failed: Unregistered type PyQt_PyObject passed in arguments даже без доступа к dbus - person svalo; 23.01.2015
comment
@свало. Возможно, вам придется использовать QByteArray (см. мой обновленный ответ). Я не могу проверить это сам, так что извините за догадки. Кажется странным, что PyQt не обрабатывает это автоматически — может быть, где-то есть ошибка? - person ekhumoro; 23.01.2015
comment
Хорошо, спасибо . Я попробовал foo='test',test=QByteArray(foo.encode('utf-8')),print(type(test)) -> <class 'PyQt5.QtCore.QByteArray'> , вызов его с помощью result = self.fpiudaemon.call('sign', [test], options) дает Interface; member=sign array [ variant array of bytes "test"] и снова не массив строк - person svalo; 28.01.2015
comment
@свало. Ну, я подозреваю, что это либо ошибка, либо очень, очень неинтуитивный API. Из вашего исходного примера ясно, что PyQt может создавать невариантные строки, потому что они используются для ключей ввода dict. Кажется, это просто элементы массива и значения записей в словаре, которые преобразуются в варианты. Интересно, преобразуются ли строковые значения вне контейнеров в варианты? Если нет, то это явно указывает на какую-то ошибку (или неправильную функцию). - person ekhumoro; 28.01.2015
comment
Я успешно отправляю строки за пределы контейнера, dbus видит их как строки, а не как варианты строк, так что да, возможно, вы правы. Я спрошу людей PyQt - person svalo; 29.01.2015

5 лет спустя появляется ответ!

Вы можете указать сигнатуру типа аргумента dbus с помощью QDbusArgument. Вот пример:

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

Очевидно, убедитесь, что ваши данные могут быть преобразованы непосредственно в указанный вами тип.

person Ripdog    schedule 06.01.2020
comment
Не публикуйте один и тот же ответ в нескольких сообщениях, вместо этого вы должны пометить вопрос как дубликат, если у вас есть права. - person eyllanesc; 06.01.2020
comment
Я не думаю, что знаю. Этот вопрос является единственным результатом в Google для моих запросов по этой проблеме, поэтому я хотел убедиться, что любой, кто попадет сюда, получит ответ. - person Ripdog; 06.01.2020
comment
Ну, для этого достаточно, чтобы вы сами ответили на свой вопрос, так как другие найдут ваш ответ так же, как вы нашли этот вопрос. - person eyllanesc; 06.01.2020