Подключение к LO из Python IDE с PyUNO для отладки

Я пытаюсь создать удобную среду для разработки некоторых скриптов Python для LibreOffice Calc.

Раньше я пытался редактировать файлы .py напрямую из «/home/user/.config/libreoffice/4/user/Scripts/python/». Это не дало бы мне отладить скрипт, потому что, если я запущу его в режиме отладки, большинство компонентов, таких как XSCRIPTCONTEXT, не будут найдены.

Я решил подключиться к LO напрямую через uno из моего venv в другом месте.

Я запускаю свою виртуальную среду с помощью python -m venv --system-site-packages venv и активирую ее.

Теперь which python дает ../somefolder/venv/bin/python и pip list показывает pyuno (version 0.1.1) и unoserver (version 1.3).

Обновлено: я установил их с помощью pip из виртуальной среды. Я только что понял, что pyuno в pip-repo — это совсем другое (https://pypi.org/project/pyuno/), и я удалил его и его зависимости. Итак, внутри unoserver установлен только venv, а uno-путь: /usr/lib/libreoffice/program/uno.py

Затем я начинаю unoserver с unoserver &. Это создало процесс soffice, прослушивающий localhost:2002, который я проверил с помощью netstat -anpe | grep "2002".

Затем я открываю документ calc. Как упоминалось здесь: https://ask.libreoffice.org/t/why-does-desktop-getcurrentcomponent-return-none-in-pyuno/59902 вы должны сделать это перед запуском скрипта, скажем, MySpreadsheet.ods и попробовать tu запустите следующий скрипт (адаптировано из ссылки):

import uno
# import time

context = uno.getComponentContext()
resolver = context.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", context)
ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager

desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)

doc = desktop.getCurrentComponent()
print(doc.Title)

После проверки переменных я вижу, что все переменные созданы. Я не знаю, что искать во всех них, чтобы проверить процесс, но когда строка desktop = ... выполняется, этот объект рабочего стола имеет все поле None:

ComponentWindow: None
ContainerWindow: None
CurrentComponent: None
etc

что приводит к тому, что desktop.getCurrentComponent() также оценивается как None.

Обновлено: при выполнении кода я напечатал созданную последовательность объектов и возвращает это:

контекст:

pyuno object (com.sun.star.uno.XComponentContext)0x558e2a7a1b20{, supportedInterfaces = {com.sun.star.uno.XComponentContext,com.sun.star.container.XNameContainer,com.sun.star.lang.XTypeProvider,com.sun.star.uno.XWeak,com.sun.star.lang.XComponent}}

резольвер

pyuno object (com.sun.star.uno.XInterface)0x558e2a941c60{implementationName=com.sun.star.comp.bridge.UnoUrlResolver, supportedServices = {com.sun.star.bridge.UnoUrlResolver}, supportedInterfaces = {com.sun.star.lang.XServiceInfo,com.sun.star.bridge.XUnoUrlResolver,com.sun.star.lang.XTypeProvider,com.sun.star.uno.XWeak}}

ctx

pyuno object (com.sun.star.uno.XInterface)0x7f1d88002b58{, supportedInterfaces = {com.sun.star.uno.XComponentContext,com.sun.star.container.XNameContainer,com.sun.star.lang.XTypeProvider,com.sun.star.uno.XWeak,com.sun.star.lang.XComponent}}

smgr

pyuno object (com.sun.star.lang.XMultiComponentFactory)0x7f1d88002e78{implementationName=com.sun.star.comp.cppuhelper.bootstrap.ServiceManager, supportedServices = {com.sun.star.lang.MultiServiceFactory,com.sun.star.lang.ServiceManager}, supportedInterfaces = {com.sun.star.lang.XServiceInfo,com.sun.star.lang.XMultiServiceFactory,com.sun.star.lang.XMultiComponentFactory,com.sun.star.container.XSet,com.sun.star.container.XContentEnumerationAccess,com.sun.star.beans.XPropertySet,com.sun.star.beans.XPropertySetInfo,com.sun.star.lang.XEventListener,com.sun.star.lang.XInitialization,com.sun.star.lang.XTypeProvider,com.sun.star.uno.XWeak,com.sun.star.lang.XComponent}}

Этот ответ на другой пост: https://stackoverflow.com/a/19158549/15452958 предлагает установить PYTHONPATH на /usr/lib/libreoffice/program. Действительно, pyuno.so доступен в этой папке, и во время отладки я могу убедиться, что uno загружается из /usr/lib/libreoffice/program/uno.py.

Принятый ответ здесь: Почему desktop.getCurrentComponent() возвращает None в PyUNO? показывает, что мне следует подождать, пока desktop станет онлайн. Я пытался, и это не сработало. Я дал ему поработать так минут 5 или около того, и doc все еще оставался None.

EDIT2: вывод netstat -anpe | grep "2002" теперь считывает две дополнительные строки для установленного соединения.

tcp        0      0 127.0.0.1:2002          0.0.0.0:*               LISTEN      1000       13310724   213378/soffice.bin  
tcp        0      0 127.0.0.1:51848         127.0.0.1:2002          ESTABLISHED 1000       818657597  292648/python       
tcp        0      0 127.0.0.1:2002          127.0.0.1:51848         ESTABLISHED 1000       815824701  213378/soffice.bin 

В документации более старой версии unoconv упоминается этот ресурс: [Учебник] Импорт модуля uno в другую установку Python http://user.services.openoffice.org/en/forum/viewtopic.php?f=45&t=36370&p= 166783

Насколько я понимаю, в данном случае это не имеет значения, так как libreoffice все равно использует системный python в Linux.

Я попытался запустить wget -O find_uno.py https://gist.githubusercontent.com/regebro/036da022dc7d5241a0ee97efdf1458eb/raw/find_uno.py python3 find_uno.py, как показано на unoserverreadme, и это дало мне только системный путь python.

Что мне не хватает? Любые подсказки или предложения приветствуются.

Также, если возможно, кто-нибудь может объяснить последовательность: context, resolver,ctx, smgr, desktop и что эти объекты означают с точки зрения непрофессионала?

Похоже, вы пытаетесь настроить отладку в специальной виртуальной среде, но, возможно, более типичный старт был бы разумнее. Вы работали с учебным пособием на christopher5106.github.io/office/2015/12/06/… со стандартной настройкой?

Jim K 18.04.2023 14:22

Спасибо за ссылку. Я просмотрел его в начале, но теперь, после некоторой борьбы, я могу оценить его лучше. Я уже пробовал это так: «Два других способа - вставить ваш скрипт либо глобально на ваш компьютер, либо в вашу локальную установку LibreOffice». и это сработало. Мне удалось написать скрипт для базового функционала, который работал, хотя это было немного больно. В основном потому, что не было автодополнения и отладки. Теперь, когда я хочу расширить его, и я думаю, что для этого потребуются гораздо более сложные вызовы, поэтому я хочу настроить способ с отладкой/автокомпьютером. возможность

laksdjfg 18.04.2023 16:18

В разделе «Первая игра с оболочкой Python для ознакомления» он точно описывает, чего я хочу достичь, и, похоже, это работает. Я запускаю те же команды (хотя я получил их из другого места), и у меня это не работает. Хотя ясно, что связь с libre office в порядке, так как я могу получить все объекты, кроме последнего. Любое другое решение, которое позволяет мне добиться отладки и завершения, также более чем приветствуется.

laksdjfg 18.04.2023 16:22

Я только что понял, извините за путаницу с этим: «Я просто хочу изменить некоторые ячейки ..: D», я думал, что это проблема «быстрого решения», я удалил ее сейчас;)

laksdjfg 18.04.2023 16:32

Судя по этим комментариям, вы застряли где-то в учебнике. Вы успешно ввели soffice --calc --accept = "socket,host=localhost,port=2002;urp;StarOffice.Ser‌​viceManager" в терминал и видите окно? Если да, то смогли ли вы запустить оболочку Python и ввести код от import uno до model = desktop.getCurrentComponent()? Я лично выполнял эти шаги много раз в разных системах, поэтому все должно работать, если вы делаете их правильно, если только ваша система не отличается чем-то другим. Пожалуйста, также укажите вашу операционную систему и версию LO.

Jim K 19.04.2023 16:10

Еще одно замечание: если вы надеетесь настроить функции отладки или автозаполнения, возможно, это потому, что вы хотели бы в какой-то момент взяться за более крупный проект. Если это так, позвольте мне сказать следующее в качестве ободрения: я не уверен, настроите ли вы эту функциональность, но в целом программирование с помощью UNO API становится проще позже, и это очень удобно для создания больших проектов. используя питон-уно. Борьба происходит в основном на ранних стадиях, когда есть чему поучиться. Вспомогательные средства, включая МРТ и, возможно, расширение APSO, важны.

Jim K 19.04.2023 16:21

Также стоит упомянуть, что моя установка состоит из текстовых редакторов с подсветкой синтаксиса Python, а также библиотек ведения журналов, обработки исключений, модульного тестирования и pylint. Он гибкий и его проще настроить, чем тесно интегрированные инструменты, о которых вы спрашиваете. В частности, для pylint я создал набор подделок на основе документации API UNO, чтобы он принимал эти объекты как действительный код. Если API когда-нибудь изменится или мне понадобится новый тип объекта, я добавлю новый файл в коллекцию подделок, но это случается не так уж часто.

Jim K 19.04.2023 17:02

Кстати, какая у вас IDE? Если это PyCharm, я дал ответ об этом несколько лет назад: stackoverflow.com/questions/37182660/….

Jim K 19.04.2023 17:39

Ах глупый я :). unoserver запускается libreoffice в режиме headless. Вот полная команда: INFO:unoserver:Command: libreoffice --headless --invisible --nocrashreport --nodefault --nologo --nofirststartwizard --norestore -env:UserInstallation=file:///tmp/tmpe3v276_k --accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;St‌​arOffice.ComponentCo‌​ntext. В основном я делал это, запуская процесс headless, затем открывая графический интерфейс в отдельном и удивляясь, почему он не дает мне объект графического интерфейса: D. После попытки с вашей командой, конечно, для этого процесса был создан графический интерфейс.

laksdjfg 20.04.2023 00:28

слушал сокет, и он работал безупречно, а затем щелкал. Должен ли я опубликовать ответ, вы хотите? Моя IDE — vscode. Может быть, вы могли бы также подробно описать свой подход, кажется интересным. Я не понимаю часть "коллекция подделок". Я думаю, что это может быть полезно для людей, наткнувшихся на это (таких как я).

laksdjfg 20.04.2023 00:28
Почему в 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
10
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

(Ответ адаптирован из комментариев, которые привели к решению проблемы):

Обязательно ознакомьтесь с руководством по адресу http://christopher5106.github.io/office/2015/12/06/openoffice-libreoffice-automate-your-office-tasks-with-python-macros.html.

Судя по комментариям, вы застряли где-то в учебнике. Вы успешно ввели в терминал следующее и видите ли вы появившееся окно:

soffice --calc  --accept = "socket,host=localhost,port=2002;urp;StarOffice.ServiceManager"

Вы также просили предоставить дополнительную информацию о подделках pylint . После дальнейшего чтения, я не думаю, что это будет актуально для вас. В любом случае, например, если pylint жалуется на объекты UNO при использовании отдельного дистрибутива Python в Windows для проверки статического кода, обходным путем является создание каталога pylint-fakes, как описано в https://stackoverflow.com/a/9616857/5100564 . Например, если pylint не находит XActionListener, вы можете создать файл с именем pylint-fakes/com/sun/star/awt/__init__.py со следующим фиктивным кодом:

class XActionListener():
    pass

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