KritaのPythonプラグインを作る方法を調べた

# 概要

KritaでPythonプラグインを作成する方法を調べたけども英語版の資料しかないので、日本語でその内容をまとめてみた。
といっても[KritaのPython Scriptingページの序盤](https://docs.krita.org/en/user_manual/python_scripting.html)をやってみただけなのでその記録。
**この文書およびここのソースはGFDLライセンスです。**(というのもマニュアルのページは全てGFDLライセンスでありそこからの引用及び改変ソースが含まれてるためです。)

# 前提条件

LinuxにKritaをインストールする。おそらくバージョンは4.0以降。あとはテキストエディタが使える状態で端末ソフトを起動しておく。
今回はUbuntu18.04でvimとGNOME Terminalを使用した。Kritaのバージョンは4.0.1。

# 手順

## 準備

### フォルダ作成
[How to make a Krita Python plugin](https://docs.krita.org/en/user_manual/python_scripting/krita_python_plugin_howto.html)にて指定されていた2つのフォルダが必要となるので、作成。以下に役割と名称を示す。

#### リソースフォルダ(原文での表記は「resources folder」)
pythonで記された外部プラグインを格納するためのフォルダ。デフォルトの状態ではホームディレクトリ内の.local/share/krita/pykrita/である。今回はここにあるものとして作業をすすめる。ないならmkdirコマンドあたりで作成する。
#### プラグインフォルダ(原文での表記は「plugin folder」)
リソースフォルダの中に作成されるプラグインごとに作成されるフォルダ。
この中にプラグインのソースコードを入れる。
今回はmypluginというフォルダ名とする。

まとめて作るなら以下のコマンドを実行。

```shell
$ mkdir -p ~/.local/share/krita/pykrita/myplugin
```

### 必要ファイル作成

#### デスクトップファイル

iniファイル形式で、デスクトップファイルを作成する。作成する場所はリソースフォルダ内。拡張子は.desktopである。
プラグインごとにこのファイルは作成する必要がある。


```ini:~/.local/share/krita/pykrita/hoge.desktop
[Desktop Entry]
Type=Service
ServiceTypes=Krita/PythonPlugin
X-KDE-Library=myplugin
X-Python-2-Compatible=false
X-Krita-Manual=myPluginManual.html
Name=My Own Plugin
Comment=Our very own plugin.
```

[How to make a Krita Python plugin](https://docs.krita.org/en/user_manual/python_scripting/krita_python_plugin_howto.html)によると、値のそれぞれの意味については以下のとおり。

##### Type
Serviceで固定。
##### ServiceTypes
Krita/PythonPluginで固定。
##### X-KDE-Library
このデスクトップファイルに対応するプラグインフォルダのファイル名。
##### X-Python-2-Compatible
Python2のソースコードが含まれるかどうか。DENABLE_PYTHON_2が有効であれば値自体が不要。
##### X-Krita-Manual
プラグインフォルダ内に書かれてる、このプラグインの説明を記したマニュアルのファイル名。
##### Name
プラグインを有効化するためにプラグインの一覧を表示する際に表される、このプラグインの名称。
##### Comment
プラグインを有効化するためにプラグインの一覧を表示する際に表される、このプラグインの説明。

#### pythonスクリプト
プラグインのエントリポイントおよびソースコードは\_\_init\_\_.pyというソースファイル。
これをプラグインフォルダに入れるとKrita起動時にこのスクリプトが実行される。
他のソース読む場合には普通にimportする。
今回はプラグインフォルダの中にあるimp.pyというソースをインポートして、そこで宣言されたExtensionの継承クラスMyExtensionのインスタンスを追加する。
<details><summary>Extensionとはkrita起動時に読み込まれるプラグインのソースを記述する雛形のようなものらしい。</summary>
createActionsに挙動を記すことでそのプラグインがどういう動きをするかを記すらしい。
らしい、というのも以下の公式の説明文でExtensionとは何なのかがいまいちよくわからなかった。詳細を説明できる方がいましたら説明お願いします。
[How to make a Krita Python plugin](https://docs.krita.org/en/user_manual/python_scripting/krita_python_plugin_howto.html)
[Extensionのクラス説明文](https://api.kde.org/extragear-api/graphics-apidocs/krita/libs/libkis/html/classExtension.html)</details>

このソースは、Tools > Scriptingの項目に、「My Script」という項目を追加するのみのソース(公式のソースにコメントを付け足しただけ)である。

```python:~/.local/share/krita/pykrita/myplugin/__init__.py
from .imp import * # 他のソースを読み込む

# Krita.instanceに、他のソースで作成したExtensionを登録
Krita.instance().addExtension(MyExtension(Krita.instance()))
```

```python:~/.local/share/krita/pykrita/myplugin/imp.py
import sys
from krita import *

class MyExtension(Extension):

    def __init__(self, parent):
        #This is initialising the parent, always  important when subclassing.
        super().__init__(parent)

    def setup(self):
        pass

    def createActions(self, window):
        action = window.createAction("myAction", "My Script", "tools/scripts") # ウィンドウに対して、toolsのScriptingの項目に、My Scriptという項目を追加する。
```

### 有効化
Settings > Configure Krita > Python Plugin Managerにて、デスクトップファイルで指定したNameの名前にチェックをつけ、Kritaを再起動する。
そうすると、プラグインが有効化し、Tools > Scriptingに、「My Script」という項目が追加される。
(再起動しないとスクリプトを読み込まないため、有効化されないので注意。)

# これ以上の内容について

参考文献においた公式のユーザーマニュアルに、いろいろな内容が記述されているので、そこを参照。

# 参考文献
[Kritaユーザーマニュアル Python Scripting](https://docs.krita.org/en/user_manual/python_scripting.html)
[Kritaユーザーマニュアル Introduction to Python Scripting](https://docs.krita.org/en/user_manual/python_scripting/introduction_to_python_scripting.html)
[Kritaユーザーマニュアル How to make a Krita Python plugin](https://docs.krita.org/en/user_manual/python_scripting/krita_python_plugin_howto.html)
[Krita KDE API ReferenceのExtensionのクラス説明文](https://api.kde.org/extragear-api/graphics-apidocs/krita/libs/libkis/html/classExtension.html)