PythonプログラムでGUIを作成するkivyでスクロール可能なラベルのカスタムウィジェットを作ったメモ
Pythonのマルチプラットフォーム向けGUIライブラリkivyでお試しプログラムを作っていた時、 ログ出力をスクロール可能にしたい(TeraTermみたいなターミナル表示のイメージ)と思い作ってみたけれど、 汎用的に使えそうな気がしたのでカスタムウィジェットとしてまとめてみた。
解説するほど理解してないけど…
kivyでは文字列を表示するのにLabelウィジェットを使うらしい(AndroidStudioでいうことろのTextView?)。
で、表示をスクロールするにはScrollViewウィジェットを使う(AndroidStudioでもScrollView)。
文字列をスクロールするには、ScrollViewの中にLabelを配置してやれば良いのだけれど、「配置しておしまい」という訳でもなく、
色々と細々と下処理が必要になる。
まずは、表示をどの程度残すか。TeraTermやWindowsTerminalでもスクロールバッファ行数や履歴のサイズとして指定する項目。
これを設定できないと際限なく表示が増えてしまうので。
これを実現するため、表示内容をdequeに保存し、新規行を追加した際にあふれた分を自動的に破棄するようにしている。
また、テキストが表示領域からあふれた際に自動的にスクロールするようにするため、ラベルのtexture_size
プロパティが変更された際に
イベントハンドラupdate_label_size
がコールされるように設定。
self.label.bind(texture_size=self.update_label_size)
ここでラベルのサイズをテクスチャサイズに合わせて変更している。
また、このときラベルサイズがスクロールビューのサイズを超えた時、self.scroll_y
を0,0
に設定することで
最下行を表示できるようにしている。
なお、ラベルサイズがスクロールビューのサイズ以下の時にself.scroll_y
を0,0
にしてしまうと下付き表示になってしまうため、
この条件ではself.scroll_y
を1,0
にしている。
ラベルサイズがスクロールビューのサイズ以上の時に常にself.scroll_y
を0,0
にすると
以前の内容を確認するためにスクロールしている状態で新しい行が表示されると最下行までスクロールしてしまうので、
0.0
に設定するのはスクロールビューのサイズを超えた時だけにしている。
ScrollLabel
クラスをインポートして使ってください。
from scrolllabel import ScrollLabel
設定できるプロパティはScrollView
のプロパティにrows
(バッファ行数)を追加しています。
プロパティにrows
は初期化時にのみ変更可能です。
初期化後(実際は最初のテキスト出力後)は変更してもバッファ行数に反映されません。
テキストを追加するにはadd_text(text)
を使用します。
引数end
を指定することで行末文字を変更できます(デフォルトは\n
)。
テキストを消去するにはclear_text()
を使用します。
gistにupしたので、gistの埋め込みリンク貼っとく。
もしダウンロードしたいときは
こちら
からどうぞ。
また、gistには実際に使用する際の例(レイアウトに Kv language使用/python使用)も載せてあるのでよろしかったら見てください。