Inkscape Extension: Python Doesn't Invoke .exe
Solution 1:
Inkscape uses Python 2.7, which it brings with it, unless you set that differently in the settings file (edit manually).
If you want to write an Inkscape extension, you can learn how to do this by:
- reading https://inkscape.org/develop/extensions/
- following the examples in other extensions that work (e.g. for running additional Inkscape instances, you could follow this one: https://gitlab.com/su-v/inx-pathops/blob/master/src/pathops.py)
Solution 2:
Loosely based on the pathops.py file, linked by Moini in her answer, I've come up with the following file.
About
It uses the inkex.py (source on GitLab) library to declare an Inkscape Effect
. The Effect
class uses the OptionParser
library to parse the default given parameters (e.g. --id=$$
for selected nodes where $$
is the XML node's 'id' tag's value). By adding the custom executable
option, we can also parse this.
Parsing arguments
After the OptionParser
is done parsing, the values will be visible in self.options
, i.e. our executable now lives in self.options.executable
(because of the action="store"
and dest="executable"
parameters).
Furthermore, the temporary SVG-file as created by Inkscape, can be found in self.svg_file
.
Saving edits
As previously said, Inkscape makes a temporary file with the contents of the SVG in its then current state. Any edits you(r plugin) make(s) should not be saved back to this file, but returned to Inkscape itself - this is the premise of the Effect
class: it edits an SVG and returns the edit to Inkscape. Further reading here.
Instead, in your plugin you should (readonly) open the file, read its contents, and then edit it. When you're done editing, write the entire SVG to your commandline.
Then, the line out, err = process.communicate(None)
will grab your plugin's output and error-output. These are used to return information to Inkscape.
Notes
The structure of the cmd
array is of no importance, except the fact that the executable should come as the very first element. All other array-elements can be anything in any order, I just added '--id=$$'
to every ID because that's the way Inkscape uses, and this way it looks the same as if there's no Python middleware present. The same goes for the self.svg_file
which I placed last, Inkscape does the same in its arguments - you could also make '--file='+self.svg_file
from it for clarity.
Source
#!/usr/bin/env pythonimport os
from subprocess import Popen, PIPE
import time
try:
import inkex_local as inkex
except ImportError:
import inkex
#import simplestyleclassMyPlugin(inkex.Effect):
def__init__(self):
inkex.Effect.__init__(self)
self.OptionParser.add_option("--executable", action="store", type="string", dest="executable", default="MyPlugin.exe")
defeffect(self):
out = err = None
cmd = []
cmd.append(self.options.executable)
foridin 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 isnotNone:
inkex.errormsg(err)
if __name__ == '__main__':
myplugin = MyPlugin()
myplugin.affect()
Post a Comment for "Inkscape Extension: Python Doesn't Invoke .exe"