Попытка получить доступ к Inkscape через d-bus не удалась (но работает с Gio)

Я пытаюсь использовать dbus для управления Inkscape из сценариев.

Этот код, который я получил отсюда, работает нормально:


#  Start after inkscape is running.
print ("DBus test")

import gi

gi.require_version("Gio", "2.0")
from gi.repository import Gio, GLib

try:
   bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)

except BaseException:
   print("No DBus bus")
   exit()

print ("Got DBus bus")

proxy = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None,
                              'org.freedesktop.DBus',
                              '/org/freedesktop/DBus',
                              'org.freedesktop.DBus', None)

names_list = proxy.call_sync('ListNames', None, Gio.DBusCallFlags.NO_AUTO_START, 500, None)

# names_list is a GVariant, must unpack

names = names_list.unpack()[0]

# Look for Inkscape; names is a tuple.

for name in names:
   if ('org.inkscape.Inkscape' in name):
       print ("Found: " + name)
       break

print ("Name: " + name)

appGroupName = "/org/inkscape/Inkscape"
winGroupName = appGroupName + "/window/1"
docGroupName = appGroupName + "/document/1"

applicationGroup = Gio.DBusActionGroup.get( bus, name, appGroupName)
windowGroup = Gio.DBusActionGroup.get(bus, name, winGroupName)
documentGroup = Gio.DBusActionGroup.get(bus, name, docGroupName)

# Activate actions. Draw a few objects first.

applicationGroup.activate_action('select-all', GLib.Variant.new_string('all'))
applicationGroup.activate_action('object-rotate-90-cw', None)

windowGroup.activate_action('tool-switch', GLib.Variant.new_string('Arc'))
windowGroup.activate_action('canvas-zoom-page', None)

Когда я пытаюсь перевести это, чтобы использовать dbus вот так:

#!/usr/bin/env python

# Start after Inkscape is running.

import dbus
from xml.etree import ElementTree as ET

print("DBus test")

try:
    # Connect to the session bus
    bus = dbus.SessionBus()
except dbus.exceptions.DBusException as e:
    print(f"No DBus bus: {e}")
    exit()

print("Got DBus bus")

# Get the list of names on the bus
proxy = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
interface = dbus.Interface(proxy, 'org.freedesktop.DBus')
names = interface.ListNames()

# Look for Inkscape
name = None
for n in names:
    if 'org.inkscape.Inkscape' in n:
        name = n
        print(f"Found: {name}")
        break

if not name:
    print("Inkscape not found")
    exit()

print(f"Name: {name}")

appGroupName = "/org/inkscape/Inkscape"
winGroupName = appGroupName + "/window/1"
docGroupName = appGroupName + "/document/1"

def activate_action(group, action, parameter=None):
    try:
        group.Activate(action, parameter, dbus_interface='org.gtk.Actions')
        print(f"Activated action: {action} with parameter: {parameter}")
    except dbus.exceptions.DBusException as e:
        print(f"Failed to activate action {action}: {e}")

applicationGroup = bus.get_object(name, appGroupName)
windowGroup = bus.get_object(name, winGroupName)
documentGroup = bus.get_object(name, docGroupName)

# Activate actions. Draw a few objects first.
activate_action(applicationGroup, 'select-all', 'all')
activate_action(applicationGroup, 'object-rotate-90-cw')

это терпит неудачу с этим сообщением:

ERROR:dbus.connection:Unable to set arguments ('select-all', 'all') according to signature 'sava{sv}': <class 'TypeError'>: More items found in D-Bus signature than in Python arguments
Traceback (most recent call last):
  File "/home/simone/inkscape_experiments/dbus_05.py", line 54, in <module>
    activate_action(applicationGroup, 'select-all', 'all')
  File "/home/simone/inkscape_experiments/dbus_05.py", line 44, in activate_action
    group.Activate(action, parameter, dbus_interface='org.gtk.Actions')
  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 72, in __call__
    return self._proxy_method(*args, **keywords)
  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 141, in __call__
    return self._connection.call_blocking(self._named_service,
  File "/usr/lib/python3/dist-packages/dbus/connection.py", line 643, in call_blocking
    message.append(signature=signature, *args)
TypeError: More items found in D-Bus signature than in Python arguments

В чем здесь проблема? Есть ли способ проверить сигнатуры d-bus и использовать их для правильного вызова вещей?

ошибка не показывает, какая строка в вашем коде вызывает эту проблему. Мне кажется, что функции в D-Bus нужно больше значений, чем отправляет Python. Вы искали More items found in D-Bus signature than in Python arguments в Google или на Stackoverflow? Возможно у кого-то была подобная проблема и он нашел решение.

furas 13.06.2024 01:26

Получить «состояние» из dbus с помощью Python – 1 Ответ

furas 13.06.2024 01:30

Вы видели это DBus - Inkscape Wiki? Какую версию Inkscape вы используете? кажется, новая версия должна использовать Gio

furas 13.06.2024 01:41
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ошибка показывает signature 'sava{sv}'.

я нашел

И все это может означать, что 'sava{sv}' означает 's,av,a{sv}' и может потребоваться:
String, Array of Variants (список), Array of Strings and Variants (диктовать)

group.Activate(String, [Variant, ...], {String:Variant, ...})

Итак, я протестировал

group.Activate('select-all', ['all'], {}, dbus_interface='org.gtk.Actions')
group.Activate('object-rotate-90-cw', [], {}, dbus_interface='org.gtk.Actions')

И это работает для меня.


Наконец я создал функцию с *args и **kwargs.

def activate_action(group, action, *args, **kwargs):  # with * and **
    try:
        # without * and ** to keep it as list and dict
        group.Activate(action, args, kwargs, dbus_interface='org.gtk.Actions')
        print(f"Activated action: {action} with parameters: args:{args} kwargs:{kwargs}")
    except dbus.exceptions.DBusException as e:
        print(f"Failed to activate action {action}: {e}")


activate_action(applicationGroup, 'select-all', 'all')
activate_action(applicationGroup, 'object-rotate-90-cw')

Другие вопросы по теме