お絵描きソフトInkscape(インクスケープ)の使い方を初級レベルから上級レベルまで広く紹介しています。
情報追加のリクエストや分かりにくい点があれば下のCONTACTフォームからどうぞ。

Inkscapeの自作エクステンション(ダイアログ)

  Inkscapeでエクステンションを自作する方法を試してみました。

 ここでは、Pythonプログラムを実行する直前に、そのPythonプログラムにパラメータを設定するためのダイアログを表示させるという機能を使ってみました。

 ただし、具体的なパラメータの渡し方はとりあえず置いておいて、画面にダイアログを表示してみただけです。

 エクステンション設定用のダイアログは「Extension Definition ファイル」の中でXMLを使って定義します。すると、そこに定義された部品を配置したダイアログをInkscapeが生成して表示してくれます。そしてこのダイアログ上の「適用」ボタンを押すか、または、「ライブプレビュー」にチェックを入れると、Pythonプログラムが起動されて、ダイアログ上に設定した値が起動されたPythonプログラムに渡されるようになっています。

 まずは「Extension Definition ファイル」ですが、今回のお試しでは、タイプ(type)に「notebook」と指定することでタブ画面を作り、そのタブ画面に「page_1」と「page_2」という2枚のタブを並べ、各タブには「desc_1」と「desc_2」という固定文字列を表示させています。

<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
  <name>ダイアログを出す</name>
  <id>com.blogspot.inkscape-memorandum.ダイアログを出す</id>
  <param name="name_1" type="notebook">
<page name="page_1" gui-text="ページ1">
   <param name="desc_1" type="description">説明1</param>
     </page>
     <page name="page_2" gui-text="ページ2">
   <param name="desc_2" type="description">説明2</param>
     </page>
  </param>
  <effect>
    <effects-menu>
      <submenu name="◆◆ 自作 ◆◆"/>
    </effects-menu>
  </effect>
  <script>
    <command location="inx" interpreter="python">ダイアログを出す(コード).py</command>
  </script>
</inkscape-extension>


 これだけで、「ダイアログを出す」エクステンションをメニューから選ぶと次のようなダイアログが表示されます。


 タブ画面や表示文字列(description)はエクステンションに対する設定パラメータではないのに「param」という要素で記述するようになっているのが少し妙な感じがします。

 ここで「適用」ボタンを押すなどすると「ダイアログを出す(コード).py」が起動され、「effect」メソッドが呼び出されることになると思いきや、これだけでは書くべきコードが足りなくて、次のようなエラーが表示されてしまい「effect」メソッドを呼び出す前に異常終了してしまいます。


 なぜこのエラーが出るようになっているのかはわかりませんが、ダイアログ画面を作ってそこにパラメータを設定できるようにするだけではダメで、Pythonプログラムの中で「どんなパラメータを設定対象として追加したのか」を教えてあげる(登録する?)処理を実行する必要があるのだそうです。そうだとすると「Extension Definition ファイル」で定義したパラメータをプログラムコードのほうでも設定することになるので、重複しているようにも思いますが、とにかくそうなっているそうです。(このあたりの、プログラミングインタフェースのデザインとでも言うのか、従わないといけない前提みたいなものが、直感的に理解できないと感じられてしまうのですが…)

 具体的にどんなコードを書くかというと、次のようにPythonプログラムの中に「effect()」メソッドとは別に、「add_arguments()」というメソッドを書いて、その中で「add_argument()」というメソッド(こちらは末尾の「s」が無いので注意)を使って、ダイアログで設定させるようにしたパラメータの名前と型とデフォルト値をPythonプログラムの内部に設定します。(つまりPythonプログラムに対して、どんなパラメータを設定させるようにしているかを教えてあげる)

import inkex
import sys

class DialogExtension(inkex.extensions.EffectExtension):
    def add_arguments(self, pars):
        # ↓なぜかパラメータ名の先頭に「--」を付ける
        pars.add_argument('--name_1', type=str, default='aaa')

        # ↓他のパラメータは「add」しなくてもよい(理由は不明)
        # pars.add_argument('--desc_1', type=str, default='aaa')
        # pars.add_argument('--desc_2', type=str, default='aaa')

    def effect(self):
        for elem in self.svg.selection:
            elem.style['fill'] = '#00ff00'  # フィルに緑をセット

if __name__ == '__main__': 
    DialogExtension().run()

 よくわからないのは、最初の「name_1」という名前のパラメータ(すなわちタブ画面)についてだけadd_argument()を呼べばよくて、残りの2つのパラメータ「desc_1」「desc_2」については呼ばなくてもエラーは出なくなります。

 また、add_argument()の引数に渡しているパラメータ名(name_1)は、「Extension Definition ファイル」のほうに書いたパラメータ名そのものではなく、先頭に「--」を付けたものになっています。どうしてそんなことをするのか、理由を説明してくれる解説コンテンツは見つかっていません。とにかくおまじないのようにそう書けば、エラーは出なくなるし、Pythonプログラムも実行されます。