備忘録やめた

備忘録として使用していたけどやめた.このブログに載せてあるコードのライセンスは別途記載がない限りWTFPL OR NYSLです.

KritaでGitを使うためのプラグインを作成した

github.com

TL; DR

上記リンクのREADMEを読んでください.

はじめに

最近お絵描きを始めたのですが,難しいですね.お絵描き自体の技術もそうですし,ソフトウェアの使い方もまだ身についていません.そして,色々やっていると「やっぱり前に描いたものの方が良かったかな」と思い,けれども思ったときには復元できず,手遅れということがよくあります.

で,Gitを使って版を管理しようと思いました.ただ,当然ながらそのようなプラグインは存在しなかったので,自分で作ってみることにしました.

各ソフトウェア等のバージョン

名前 バージョン
Git docker 0.1.0*1
Krita 5.0.2
Python 3.9.9
GitPython 3.1.27

インストール

以下,すべてLinuxのターミナル上で行っています.

まず,GitPythonをインストールしてください.

pip install --user GitPython

記事最初のリンクからファイルをダウンロードしたあと,gitdocker.desktopgitdocker/ディレクトリをともにpykritaディレクトリの中に移してください.pykritaディレクトリの場所はKritaリソースディレクトリの中にあります.例えばLinuxなら以下のように.

git clone https://github.com/toku-sa-n/Krita-git-docker
cd Krita-git-docker
cp -r gitdocker gitdocker.desktop ~/.local/share/krita/pykrita/

それから,メニューバーの「設定→Kritaの設定を変更」より設定画面を出し,PythonプラグインマネージャよりGit dockerを有効にします.なお,"No Manual Available"と表示されているのは単なる手抜きです.

Pythonプラグインマネージャのスクリーンショット
PythonプラグインマネージャよりGit dockerを有効にする

そしてKritaを再起動し,メニューバーの「設定→ドッキングパネル→Git docker」より,Git dockerのドッキングパネルを表示します.

使用法

絵の巧拙に関しては気にしないでください.

Gitリポジトリ内にあるファイルをKritaで開きます.

Gitリポジトリ内のファイルを開いた直後のKritaの画面.Git dockerのサムネイルとコンボボックスが更新されている.
KritaでGitリポジトリ内のファイルを開いた直後

Git dockerに,最後のコミットの際のサムネイルが表示されています.また,コンボボックスにはこのファイルが含まれているコミットのうち,最新の10個のコミットの要約が一覧となっています.コンボボックスで別のコミットを選択すると,サムネイルもその版のものに更新されます.

コンボボックスで別のコミットを選択した際の,Git dockerの画面.サムネイルが更新されている.
別のコミットを選択した直後

Openボタンを押すと,そのコミットにおける版をKritaの別ウィンドウで開くことが出来ます.なお,このファイルは一時ファイルのため,編集しても元のGitツリーには影響しません.

過去の版を開いた直後の画面
過去の版を開いた直後の画面

元のファイルに戻り,編集します.右方向の画像が欲しいので,キャンパスのサイズを拡大して,左方向のレイヤをコピペして作ります.

右方向の画像を追加した直後のKritaのスクリーンショット
右方向の画像を追加した

出来ました.ではこれをコミットしましょう.コミットメッセージを書いて,Commitボタンを押します*2*3.サムネイルは更新され,コンボボックスの一覧に新しいコミットが追加されています.なお,コミットの際に他のファイルもステージングされている場合は,それらも一緒にコミットされます.また,コミットにはGPG署名がされないことに注意してください.

"chore: add the images of moving to right"というコミットメッセージがテキストボックス内に書かれている,Git dockerのスクリーンショット.
コミットメッセージを記述する

Commitボタンを押した直後のGit dockerのスクリーンショット.コミットメッセージを記述するテキストボックスは空になり,"Commited."(タイポ.Committedが正しい)というメッセージが表示されている.それからサムネイル画像も最新のコミットを反映している.
Commitボタンを押した直後

このように,過去のコミットを確認しつつ,新たなコミットを追加することが出来ます.

Kritaのプラグインの開発について

上記からわかるように,Kritaでは,Pythonを用いて各種処理を自動化することが出来ます.これらについては公式で資料が提供されています.また,拡張機能やドッキングパネルをプラグインとして開発することも出来ます.開発の際はPyQt5とkritaのパッケージを用いることが出来ます.

import krita
import PyQt5

なお,kritaパッケージはKrita本体に付随しているため,pipで取得することが出来ません.また,ユニットテスト用のパッケージが有志によって提供されています

Kritaのプラグインを作成する場合は,拡張子が.desktopのファイルと,Pythonのパッケージが必要です.例えば今回はgitdockerという名前ですので,次のファイルが必要となります.

  • gitdocker.desktop
  • gitdocker/__init__.py
  • gitdocker/gitdocker.py

.desktopファイルには以下のような内容を記入します.

[Desktop Entry]
Type=Service
ServiceTypes=Krita/PythonPlugin
X-KDE-Library=gitdocker
X-Python-2-Compatible=false
Name=Git docker
Comment=A docker to view file revisions managed by Git.
項目 説明
Type Serviceで固定
ServiceTypes Krita/PythonPluginで固定
X-KDE-Library プラグインソースコードが含まれているディレクトリの名前
X-Python-2-Compatible Python2との互換性があるか.すでにPython2はEOLを迎えているのでfalseで問題ないはず
Name プラグインの名前
Comment プラグインの説明

次に,gitdocker/__init__.pyに以下の内容を記述します.

from .gitdocker import *

ドッキングメニューを作成する時は,DockWidgetを継承したクラスを作成します.その後,Kritaに登録します.詳細は公式ドキュメントを確認してください.なおcanvasChangedは,アクティブなキャンバスやビューが変更された時に呼び出されます.こちらはKritaソースコードのコードコメントを確認してください.

from krita import DockWidget, DockWidgetFactory, DockWidgetFactoryBase, Krita

class GitDocker(DockWidget):
  def __init__(self):
    pass

  def canvasChanged(self, canvas):
    pass

Krita.instance().addDockWidgetFactory(DockWidgetFactory(
    "gitDocker", DockWidgetFactoryBase.DockRight, GitDocker))

プラグインの動作確認の際は,Kritaを毎回再起動する必要があります.

Krita上でスクリプトを試したいときは,スクリプターが便利です.メニューバーより「ツール→スクリプトスクリプター」を辿ることで表示できます.もしスクリプトからメニューが出ない場合,プラグインマネージャを確認したり,Kritaのバージョンを確認したり,あるいは複数インストールされているPyQt5をアンインストールしてみてください.以下公式マニュアルより引用.

scripter を開くには、ツール ‣ スクリプト ‣ Scripter に行きます。もしリストになければ、設定 ‣ Krita の設定を変更... ‣ Python プラグインマネージャ からリストの "Scripter" をオンにします。もしそこにもなければ、最新版の Krita を使用しているか確認してください。

tokuchan3515.hatenablog.com

スクリプターの起動直後の画面
スクリプターの画面

テキストエリア内にPythonコードを記述して,左上の三角のボタンをクリックすると記入したスクリプトが実行されます.先程紹介したkritaやPyQt5パッケージを使うことも出来ます.

QtPy5パッケージのAPIリストはありません.その代わり,C++を用いて記述されているQtのドキュメントを利用することが出来ます.ドッキングメニューを製作する際はQt WIdgets C++ Classesのページは特に読む必要があるはずです.また,kritaパッケージに関してはドキュメントが存在すると記載されていますが,執筆現在(2022/04/03),404となっています.どうやらKDEがインフラを変更しているためだそうです.代わりに2020年10月のアーカイブを参照してください.他にもKritaリポジトリplugins/pythonに各プラグインソースコードがあるので,ここを参考にすると良いです.

なお,Kritaのプラグインを配布する際は,ライセンスをGPLにする必要があります.詳しくは公式ウェブサイトを確認してください.

感想

Pythonを書いたのはこれが初めてではなく,4年前くらいに入門書やアルゴリズムの本を購入して学習したことがあったのですが,それ以来全く書いてこなかったので,かなり苦労しました.Kritaのライブラリを利用するために静的解析ツールが使えない,故にタイポをしたり型を間違えてもエラーが実行時にしか現れない,それから動作確認をするために毎回Kritaを再起動する必要があるなどということもあり,結構大変でした.

実装途中でGitPythonのバグに引っかかった時は,気づかず2日間悩みました.詳細は以下に記載しています.

stackoverflow.com

何故かgit showの出力で得たKritaファイルが正しいZipファイルとして認識されず,取り敢えず適当なファイルに書き込もうとしてやり方がわからず,Pythonの経験がある友人氏に質問しても答えは出てこなく,仕方がないのでStackOverflowで質問し,回答が来ないので初めてBountyを設定したところで,GitPythonのissueを見ていなかったことに気が付き早速見てみると,ありました.さようなら,僕の50のReputation.

github.com

ともあれこれで問題は解消したので良かったですが,次回からは使用しているライブラリのバグトラッカーも見るべきですね.

それから,コミット機能を実装中に,大量の空のコミットを生成していたことには驚きました.Gitをコマンドラインから実行する際は,--allow-empty--allow-empty-messageを付与しない限りは空のコミットやコミットメッセージが空のコミットを生成することは出来ないのですが,GitPythonのRepo.commitはお構いなしにそのようなコミットをするので,たまたまgit logの表示を見てびっくりしました.あの時見ていなければ気づかなかったと思います.

このドッキングメニューが役に立つのかは正直疑問です.レイヤ機能のおかげで,レイヤを複製して片方を非表示にすることで差分を見ることが出来ますし,KritaとGitを組み合わせるよりも,自身がお絵描きソフトに精通するほうが良いのではないかと考えています.とはいえ,プラグインを作るのは初めての試みでしたし,Pythonで何かを作るという経験も初めてでしたので,文句は言いつつも結構楽しかったです.

*1:スクリーンショットは0.1.0をリリースする前のものです.タイポなどは0.1.0で修正されています

*2:CommitedはCommittedのタイポです

*3:ところで,何となく今までcommitlintで一般的に指定されている文法でコミットメッセージの要約を書いているのですが,コミットの粒度が小さくなると新機能追加のコミットは相対的に少なくなりますし,何かの修正といったわけでもなく,機能修正といったわけでもなく,自然とchoreの分類のコミットが増えてしまうので,そろそろこの文法で書くのを止めようかなと考えています.