はじめに
今回は、今までに作ってきたサンプルを「プラグイン」にします。プラグインとは、ソフトウェアの種類によっては「アドオン」とも呼ばれる、ソフトウェアに機能を追加できるプログラムのことです(図1)。プラグイン単体では何もできず、追加する先のソフトウェアのシステムを使って動作します。KritaではPythonスクリプトをプラグインにすることで、毎回スクリプターを起動しなくてもメニューからPythonスクリプトを実行できようになります。
図1:プラグインの一覧
また、Pythonスクリプトに「ショートカットキー」をセットします。ショートカットキーとは、例えば大抵のソフトウェアでは[Ctrl]キー+[Z]キーがUndo(アンドゥ)を実行しますよね。その機能を実行するキーがショートカットキーです。ショートカットとは「近道」と言う意味です。
プラグインを作成する
円周上に虹色に色相を徐々に変えた12個の円(図2)を描く、第4回のサンプル「circle.py」をプラグインにします。ここではスクリプトを開始する「begin_draw」関数の呼び出しをプラグインのアクションにフックするところに持ってくる以外は、第4回のサンプルに変更はありません。
図2:円周上に色相を変えた円を描く
実行するプログラム
「krita」→「pykrita」→「circle」→「circle.py」ファイルに、プラグインは「Extension」クラスを継承したクラスで作ります。Extensionクラスには、主に初期化の「__init__」メソッド、セットアップの「setup」メソッド、実行するプログラムを指定する「createActions」メソッドがあります。
実行する「create_doc」関数、「draw_circle」関数、「set_layer」関数、「begin_draw」関数は第4回の「circle.py」のままです。ここでは「createAction」メソッドでユニークな(一意の)"CreateCircleAction"をアクション名にして"円周上に円を生成"がその機能の名前です。アクションの「triggered.connect」でbegin_draw関数をフックして実行するプログラムに指定します。
・サンプルスクリプト「krita」→「pykrita」→「circle」→「circle.py」
03 | ########## プラグインクラス ########## |
04 | class CirclePlugin(Extension): |
06 | def __init__(self, parent): |
07 | super().__init__(parent) |
08 | # Krita.instance() exists, so do any setup work |
11 | # called after setup(self) |
12 | def createActions(self, window): |
13 | action = window.createAction("CreateCircleAction", "円周上に円を生成") |
14 | action.triggered.connect(begin_draw) |
15 | ########## 第4回のサンプル「circle.py」とほとんど同じ ########## |
16 | def create_doc(width,height): |
17 | doc = Krita.instance().createDocument(width, height, "Line", "RGBA", "U8", "", 300.0) |
18 | Krita.instance().activeWindow().addView(doc) |
22 | pixmap = QPixmap(doc.bounds().size()) |
23 | pixmap.fill(QColor(0,0,0,255)) |
26 | painter.setRenderHint(QPainter.Antialiasing,True) |
27 | pen = QPen(QColor(0,0,0,0)) |
29 | cx =int(doc.width()/2) |
30 | cy = int(doc.height()/2) |
32 | for i in range(0,360,30): |
33 | color = QColor.fromHsl(i, 255, 128, 96) |
35 | painter.setBrush(brush) |
37 | painter.translate(cx,cy) |
39 | painter.drawEllipse(QPoint(180,0),r,r) |
42 | return pixmap.toImage() |
44 | def set_layer(doc,img): |
45 | root = doc.rootNode(); |
46 | layer = doc.createNode("NewLayer","paintLayer") |
47 | root.addChildNode(layer, None) |
48 | if img.sizeInBytes() == 4 * layer.channels()[0].channelSize() * doc.width() * doc.height(): |
50 | ptr.setsize(img.byteCount()) |
51 | layer.setPixelData(QByteArray(ptr.asstring()), 0, 0, doc.width() , doc.height()) |
56 | doc = create_doc(800,800) |
57 | img = draw_circle(doc) |
59 | doc.refreshProjection() |
【サンプルスクリプトの解説】
PyQt5とkritaのモジュールを読み込みます。
Extensionを継承した「CirclePlugin」クラスがプラグインになります。
__init__の初期化メソッド、setupのセットアップメソッド、createActionsのアクションを実行するメソッドです。
プラグインに拡張する
プラグインに拡張する「krita」→「pykrita」→「circle」→「__init__.py」ファイルで、先ほどの「circle.py」ファイルをモジュールとして読み込みます。CirclePluginクラスが「circle.py」のExtensionクラスを継承したクラスです。CirclePluginは「import」の後と「addExtension()」の中の2ヶ所に書きます。
・サンプルスクリプト「krita」→「pykrita」→「circle」→「__init__.py」
1 | from .circle import CirclePlugin |
3 | Krita.instance().addExtension(CirclePlugin(Krita.instance())) |
プラグインのエントリー
Pythonスクリプトをプラグインにエントリーするための「krita」→「pykrita」→「circle.desktop」ファイルです。「X-KDE-Library」にプログラムの「circle」をセットし、「Name」にメニュー名を、「Comment」に説明を書きます。
・サンプルスクリプト「krita」→「pykrita」→「circle.desktop」
3 | ServiceTypes=Krita/PythonPlugin |
5 | X-Python-2-Compatible=false |