Расширение Inkscape: python не вызывает.exe

Я разрабатываю плагин для Inkscape. Некоторые версии:

  • Inkscape v0.92.3
  • Windows 10, версия 1803 (сборка 17134.165)
  • Python 3.7 явно установлен
  • MonoDevelop Version 7.7 Preview (7.7) Дополнительные версии ниже

Места установки:

  • Inkscape: C: \ Program Files \ Inkscape
  • Расширение: C:\Program Files\Inkscape\share\extensions
    • Содержит: myplugin.inx, myplugin.py, MyPlugin.exe

Я сделал плагин, который по причинам разработки работает так, как задумано в настоящее время.
Наиболее важно то, что он запускается, когда я запускаю его либо из MonoDevelop, либо из самого встроенного exe-файла (как с сгенерированными DLL-файлами и т. Д. В одном месте, так и только с файлом, скопированным в другое место).

Я использую (слегка отредактированную версию) скрипт Python SugarPillStudio для запуска файла.exe. Однако когда я запускаю этот скрипт на Python, вызывая расширение,.exe не запускается. Inkscape мигает сообщением "MyPlugin запускается..." и закрывает его так же быстро, как и открывается.

Я знаю, что скрипт python работает, потому что он выводит строки отладки в файл.log на моем рабочем столе. Я знаю, что.exe не запускается, потому что он также записывает строки в тот же файл.log, во-первых, когда вызывается main(). Когда я (успешно) запускаю.exe, он печатает в файл, а когда я запускаю расширение - нет.

Это наводит меня на мысль, что есть проблема со скриптом python при вызове.exe. Любая помощь?

Python Script:

#!/usr/bin/env python
'''
sugarpillstudios.com/wp/?p=142
'''
import os, sys, subprocess, datetime

f=open("C:\Users\Diamundo\Documents\plugin.log", "a+")
f.write("[PYT] %s Python script called at: %s.\n" % (datetime.datetime.now().isoformat(), os.getcwd() ) )

argv = []  
for arg in sys.argv[:]:  
  if arg.startswith("--executable="):  
    executable = arg.split("=")[1]  
  else:  
    argv.append(arg)
argv[0] = executable  
f.write("[PYT] %s %s\n" % ( datetime.datetime.now().isoformat(), executable ) )
process = subprocess.Popen(argv,shell=False,stdout=subprocess.PIPE)
print process.communicate()[0]

Plugin.inx:

<inkscape-extension>
    <name>MyPlugin</name>
    <id>name.space.plugin.main</id>
    <param name="executable" type="string" gui-hidden="true">MyPlugin.exe</param>
    <effect>
        <object-type>all</object-type>
        <effects-menu>
            <submenu _name="MyPlugin"/>
        </effects-menu>
    </effect>
    <script>
        <command reldir="extensions" interpreter="python">myplugin.py</command>
    </script>
</inkscape-extension>

Варианты Extra Monodevelop:

Runtime:
    Microsoft .NET 4.0.30319.42000
    GTK+ 2.24.26 (Light theme)
    GTK# 2.12.45

NuGet 
Version: 4.3.1.4445

.NET Core
Runtime: C:\Program Files\dotnet\dotnet.exe
Runtime Versions:
    2.0.9
    2.0.5
SDK: C:\Program Files\dotnet\sdk\2.1.202\Sdks
SDK Versions:
    2.1.202
    2.1.4
MSBuild SDKs: Not installed

2 ответа

Решение

Исходя из файла pathops.py, на который Moini в своем ответе, я Moini следующий файл.

Около

Он использует библиотеку inkex.py ( источник на GitLab) для объявления Inkscape Effect, Effect класс использует OptionParser библиотека для анализа заданных по умолчанию параметров (например, --id=$$ для выбранных узлов, где $$ является значением тега 'id' узла XML). Добавив кастом executable вариант, мы также можем разобрать это.

Разбор аргументов

После OptionParser выполняется разбор, значения будут видны в self.options наш исполняемый файл теперь находится в self.options.executable (из-за action="store" а также dest="executable" параметры).
Кроме того, временный SVG-файл, созданный Inkscape, можно найти в self.svg_file,

Сохранение правок

Как было сказано ранее, Inkscape создает временный файл с содержимым SVG в его текущем состоянии. Любые изменения, которые вы (r плагин) делаете (и) не должны быть сохранены обратно в этот файл, но должны быть возвращены в сам Inkscape - это предпосылка Effect класс: он редактирует SVG и возвращает редактирование в Inkscape. Дальнейшее чтение здесь.

Вместо этого в вашем плагине вы должны (только для чтения) открыть файл, прочитать его содержимое, а затем отредактировать его. Когда вы закончите редактирование, напишите весь SVG в вашу командную строку.
Затем линия out, err = process.communicate(None) захватит вывод вашего плагина и вывод ошибок. Они используются для возврата информации в Inkscape.

Заметки

Структура cmd Массив не имеет значения, за исключением того факта, что исполняемый файл должен быть первым элементом. Все остальные элементы массива могут быть в любом порядке, я просто добавил '--id=$$' для каждого идентификатора, потому что именно так использует Inkscape, и таким образом он выглядит так же, как если бы не было промежуточного программного обеспечения Python. То же самое касается self.svg_file который я поместил в последний раз, Inkscape делает то же самое в своих аргументах - вы также можете сделать '--file='+self.svg_file из этого для ясности.

Источник

#!/usr/bin/env python

import os
from subprocess import Popen, PIPE
import time

try:
    import inkex_local as inkex
except ImportError:
    import inkex
#import simplestyle

class MyPlugin(inkex.Effect):
    def __init__(self):
        inkex.Effect.__init__(self)
        self.OptionParser.add_option("--executable", action="store", type="string", dest="executable", default="MyPlugin.exe")

    def effect(self):
        out = err = None

        cmd = []
        cmd.append(self.options.executable)
        for id in self.options.ids:
            cmd.append("--id=" + id)
        cmd.append(self.svg_file)
        #inkex.debug(cmd);

        process = Popen(cmd, shell=False, stdin=PIPE, stdout=PIPE, stderr=PIPE)
        out, err = process.communicate(None)

        if process.returncode == 0:
            print out
        elif err is not None:
            inkex.errormsg(err)

if __name__ == '__main__':
    myplugin = MyPlugin()
    myplugin.affect()

Inkscape использует Python 2.7, который поставляется вместе с ним, если только вы не установите это в файле настроек (отредактируйте вручную).

Если вы хотите написать расширение Inkscape, вы можете узнать, как это сделать:

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