Inkscape 扩展:python 不调用 .exe
Inkscape extension: python doesn't invoke .exe
我正在为 Inkscape 开发一个插件。部分版本:
- Inkscape v0.92.3
- Windows10,版本 1803(内部版本 17134.165)
- Python 3.7 显式安装
- MonoDevelop 版本 7.7 预览版 (7.7) 以下额外版本
安装位置:
- Inkscape: C:\Program Files\Inkscape
- 扩展名:C:\Program Files\Inkscape\share\extensions
- 包含:
myplugin.inx
、myplugin.py
、MyPlugin.exe
我制作了一个插件,出于开发原因,它可以按当前预期工作。
最重要的是,it 运行s 当我 运行 它来自 MonoDevelop 或内置的 exe 本身(两者都与生成的 .dll 等在同一个位置,或仅将 exe 复制到其他位置)。
我使用 SugarPillStudio's python script 到 运行 .exe 文件(稍微编辑过的版本)。但是,当我通过调用扩展 运行 那个 python 脚本时,.exe 没有启动。 Inkscape 会闪烁一条消息 'MyPlugin is launching...' 并在打开时尽快关闭它。
我知道 python 脚本有效,因为我将它打印调试行到我桌面上的 .log 文件中。我知道 .exe 不会启动,因为我还让它向同一个 .log 文件写入行,这是调用 main() 时的第一件事。当我(成功)运行 .exe 时它确实打印到文件,当我 运行 扩展名时它没有。
这使我相信 python 脚本在调用 .exe 时存在问题。有帮助吗?
Python 脚本:
#!/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>
额外的 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.1.202\Sdks
SDK Versions:
2.1.202
2.1.4
MSBuild SDKs: Not installed
Inkscape 使用自带的 Python 2.7,除非您在设置文件中进行了不同的设置(手动编辑)。
如果你想写一个 Inkscape 扩展,你可以通过以下方式学习如何做到这一点:
- 阅读https://inkscape.org/develop/extensions/
- 遵循其他有效扩展中的示例(例如,对于 运行 其他 Inkscape 实例,您可以遵循以下示例:https://gitlab.com/su-v/inx-pathops/blob/master/src/pathops.py)
粗略地基于 pathops.py file, linked by Moini in ,我提出了以下文件。
关于
它使用 inkex.py (source on GitLab) 库来声明一个 Inkscape Effect
。 Effect
class 使用 OptionParser
库解析默认给定参数(例如 --id=$$
用于选定节点,其中 $$
是 XML 节点的 'id' 标签的值)。通过添加自定义executable
选项,我们也可以解析这个
正在解析参数
在 OptionParser
完成解析后,值将在 self.options
中可见,即我们的可执行文件现在位于 self.options.executable
中(因为 action="store"
和 dest="executable"
参数).
此外,Inkscape 创建的临时 SVG 文件可以在 self.svg_file
.
中找到
保存编辑
如前所述,Inkscape 制作了一个 临时 文件,其中包含当时状态下的 SVG 内容。您(r 插件)所做的任何编辑都应该 不 保存回这个文件,但是 returned 到 Inkscape 本身 - 这是 Effect
class:它编辑一个 SVG 并且 returns 编辑到 Inkscape。 Further reading here.
相反,在您的插件中,您应该 (readonly) 打开文件,读取其内容,然后进行编辑。完成编辑后,将整个 SVG 写入命令行。
然后,行 out, err = process.communicate(None)
将获取您的插件的输出和错误输出。 这些 用于return Inkscape 的信息。
备注
cmd
数组的结构并不重要,除了可执行文件应该作为第一个元素这一事实。所有其他数组元素可以是任何顺序的任何东西,我只是将 '--id=$$'
添加到每个 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 开发一个插件。部分版本:
- Inkscape v0.92.3
- Windows10,版本 1803(内部版本 17134.165)
- Python 3.7 显式安装
- MonoDevelop 版本 7.7 预览版 (7.7) 以下额外版本
安装位置:
- Inkscape: C:\Program Files\Inkscape
- 扩展名:C:\Program Files\Inkscape\share\extensions
- 包含:
myplugin.inx
、myplugin.py
、MyPlugin.exe
- 包含:
我制作了一个插件,出于开发原因,它可以按当前预期工作。
最重要的是,it 运行s 当我 运行 它来自 MonoDevelop 或内置的 exe 本身(两者都与生成的 .dll 等在同一个位置,或仅将 exe 复制到其他位置)。
我使用 SugarPillStudio's python script 到 运行 .exe 文件(稍微编辑过的版本)。但是,当我通过调用扩展 运行 那个 python 脚本时,.exe 没有启动。 Inkscape 会闪烁一条消息 'MyPlugin is launching...' 并在打开时尽快关闭它。
我知道 python 脚本有效,因为我将它打印调试行到我桌面上的 .log 文件中。我知道 .exe 不会启动,因为我还让它向同一个 .log 文件写入行,这是调用 main() 时的第一件事。当我(成功)运行 .exe 时它确实打印到文件,当我 运行 扩展名时它没有。
这使我相信 python 脚本在调用 .exe 时存在问题。有帮助吗?
Python 脚本:
#!/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>
额外的 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.1.202\Sdks
SDK Versions:
2.1.202
2.1.4
MSBuild SDKs: Not installed
Inkscape 使用自带的 Python 2.7,除非您在设置文件中进行了不同的设置(手动编辑)。
如果你想写一个 Inkscape 扩展,你可以通过以下方式学习如何做到这一点:
- 阅读https://inkscape.org/develop/extensions/
- 遵循其他有效扩展中的示例(例如,对于 运行 其他 Inkscape 实例,您可以遵循以下示例:https://gitlab.com/su-v/inx-pathops/blob/master/src/pathops.py)
粗略地基于 pathops.py file, linked by Moini in
关于
它使用 inkex.py (source on GitLab) 库来声明一个 Inkscape Effect
。 Effect
class 使用 OptionParser
库解析默认给定参数(例如 --id=$$
用于选定节点,其中 $$
是 XML 节点的 'id' 标签的值)。通过添加自定义executable
选项,我们也可以解析这个
正在解析参数
在 OptionParser
完成解析后,值将在 self.options
中可见,即我们的可执行文件现在位于 self.options.executable
中(因为 action="store"
和 dest="executable"
参数).
此外,Inkscape 创建的临时 SVG 文件可以在 self.svg_file
.
保存编辑
如前所述,Inkscape 制作了一个 临时 文件,其中包含当时状态下的 SVG 内容。您(r 插件)所做的任何编辑都应该 不 保存回这个文件,但是 returned 到 Inkscape 本身 - 这是 Effect
class:它编辑一个 SVG 并且 returns 编辑到 Inkscape。 Further reading here.
相反,在您的插件中,您应该 (readonly) 打开文件,读取其内容,然后进行编辑。完成编辑后,将整个 SVG 写入命令行。
然后,行 out, err = process.communicate(None)
将获取您的插件的输出和错误输出。 这些 用于return Inkscape 的信息。
备注
cmd
数组的结构并不重要,除了可执行文件应该作为第一个元素这一事实。所有其他数组元素可以是任何顺序的任何东西,我只是将 '--id=$$'
添加到每个 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()