Я пытаюсь создать удобную среду для разработки некоторых скриптов 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 и что эти объекты означают с точки зрения непрофессионала?
Спасибо за ссылку. Я просмотрел его в начале, но теперь, после некоторой борьбы, я могу оценить его лучше. Я уже пробовал это так: «Два других способа - вставить ваш скрипт либо глобально на ваш компьютер, либо в вашу локальную установку LibreOffice». и это сработало. Мне удалось написать скрипт для базового функционала, который работал, хотя это было немного больно. В основном потому, что не было автодополнения и отладки. Теперь, когда я хочу расширить его, и я думаю, что для этого потребуются гораздо более сложные вызовы, поэтому я хочу настроить способ с отладкой/автокомпьютером. возможность
В разделе «Первая игра с оболочкой Python для ознакомления» он точно описывает, чего я хочу достичь, и, похоже, это работает. Я запускаю те же команды (хотя я получил их из другого места), и у меня это не работает. Хотя ясно, что связь с libre office в порядке, так как я могу получить все объекты, кроме последнего. Любое другое решение, которое позволяет мне добиться отладки и завершения, также более чем приветствуется.
Я только что понял, извините за путаницу с этим: «Я просто хочу изменить некоторые ячейки ..: D», я думал, что это проблема «быстрого решения», я удалил ее сейчас;)
Судя по этим комментариям, вы застряли где-то в учебнике. Вы успешно ввели soffice --calc --accept = "socket,host=localhost,port=2002;urp;StarOffice.ServiceManager" в терминал и видите окно? Если да, то смогли ли вы запустить оболочку Python и ввести код от import uno до model = desktop.getCurrentComponent()? Я лично выполнял эти шаги много раз в разных системах, поэтому все должно работать, если вы делаете их правильно, если только ваша система не отличается чем-то другим. Пожалуйста, также укажите вашу операционную систему и версию LO.
Еще одно замечание: если вы надеетесь настроить функции отладки или автозаполнения, возможно, это потому, что вы хотели бы в какой-то момент взяться за более крупный проект. Если это так, позвольте мне сказать следующее в качестве ободрения: я не уверен, настроите ли вы эту функциональность, но в целом программирование с помощью UNO API становится проще позже, и это очень удобно для создания больших проектов. используя питон-уно. Борьба происходит в основном на ранних стадиях, когда есть чему поучиться. Вспомогательные средства, включая МРТ и, возможно, расширение APSO, важны.
Также стоит упомянуть, что моя установка состоит из текстовых редакторов с подсветкой синтаксиса Python, а также библиотек ведения журналов, обработки исключений, модульного тестирования и pylint. Он гибкий и его проще настроить, чем тесно интегрированные инструменты, о которых вы спрашиваете. В частности, для pylint я создал набор подделок на основе документации API UNO, чтобы он принимал эти объекты как действительный код. Если API когда-нибудь изменится или мне понадобится новый тип объекта, я добавлю новый файл в коллекцию подделок, но это случается не так уж часто.
Кстати, какая у вас IDE? Если это PyCharm, я дал ответ об этом несколько лет назад: stackoverflow.com/questions/37182660/….
Ах глупый я :). 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;StarOffice.ComponentContext. В основном я делал это, запуская процесс headless, затем открывая графический интерфейс в отдельном и удивляясь, почему он не дает мне объект графического интерфейса: D. После попытки с вашей командой, конечно, для этого процесса был создан графический интерфейс.
слушал сокет, и он работал безупречно, а затем щелкал. Должен ли я опубликовать ответ, вы хотите? Моя IDE — vscode. Может быть, вы могли бы также подробно описать свой подход, кажется интересным. Я не понимаю часть "коллекция подделок". Я думаю, что это может быть полезно для людей, наткнувшихся на это (таких как я).






(Ответ адаптирован из комментариев, которые привели к решению проблемы):
Обязательно ознакомьтесь с руководством по адресу 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
Похоже, вы пытаетесь настроить отладку в специальной виртуальной среде, но, возможно, более типичный старт был бы разумнее. Вы работали с учебным пособием на christopher5106.github.io/office/2015/12/06/… со стандартной настройкой?