PythonでTUIアプリを作ろう ( その2 TUIライブラリの選択 )

日本語(ユニコード)対応で評価しよう。



Pythonの公式ドキュメントでは、「ターミナルアプリケーションの意義」について、下記のように指摘しています。

グラフィカルなディスプレイが当たり前の今となっては、「なんでわざわざ?」と疑問に思うかもしれません。確かに文字表示端末は時代遅れな技術ではありますが、ニッチな領域が存在していて、意匠を凝らすことができるため、いまだに価値のあるものとなっています。

それゆえ、Pythonには標準ライブラリとして、cursesが装備されているわけです。cursesライブラリは、下記の機能をPythonに付加します。

curses ライブラリは、VT100s や Linux コンソール、さまざまなプログラムが提供するエミュレーション端末といったテキストベースの端末(ターミナル)のために、端末に依存しないスクリーン描画や、キーボードの処理を提供します。端末はカーソルの移動や、画面のスクロール、領域の消去といった共通の操作を行うための様々な制御コードをサポートします。

しかしながら、

cursesが提供するユーザーインターフェースのコンセプトは限られています。ボタン、チェックボックス、ダイアログ等は含まれておりません。そのような機能が必要な場合は、Urwidのようなユーザーインターフェースライブラリーの使用を検討してください。

とのこと。ようするに、

Python標準の”curses"だけで開発するのは無理がある。

そういうことですね。


Python TUIライブラリの選択

というわけで、まずはTUIアプリ開発をサポートするライブラリを選定していきましょう。
Web上の情報などを調べていくと、なんと言ってもニッチな環境なので、候補は多くありません。現状では、下記の2つに絞って構わないと思います。

(1) Urwid

第一候補は、Pythonの標準ドキュメントにも出てくる”Urwid”でしょう。

公式サイトのChangelogを見ると、最初のバージョン0.8.0が2004年8月、最新の2.1.2が2020年9月のリリースですから、なんと17年に渡るキャリアを誇ります。

(2) npyscreen

これに対抗するのは、”npyscreen”となります。

ダウンロードサイトのRelease historyを見ると、最初のバージョン2.0pre48bが2012年4月、最新の4.10.5が2015年10月となっています。このところ動きがないのは、いささか気になるところですが、後発の強みはあるかもしれません。

この2つが代表的なものでしょう。どちらもcursesをベースに、その上にテキスト表示、ボタン、入力フィールド、リスト表示、チェックボックスなど、よく使われる部品を提供するものです。


日本語対応で評価しよう

さて、この2つのツール比較ですが、「極東の住人」にとって重要なのは、なんといってもローカル対応。
漢字が使えなければ使い物になりません。要するに、Unicode対応です。

とりあえず、簡単な入力プログラムを作って、日本語処理についてテストしてみましょう。
処理は簡単。

  • まずは、日本語で「お名前は?」と表示。
  • 定義した入力フィールドに、かな漢字変換で入力。ここでは「山田太郎」とします。

(1) Urwid

プログラムはこんな感じ。

#!/usr/bin/env python  
# -*- coding: utf-8 -*-  
#  
# s02_urwid.py  
#  
import urwid  
class MyEdit(urwid.Edit):  
    def keypress(self, size, key):  
        if key != 'enter':  
            return super(MyEdit, self).keypress(size, key)  
        else:  
            raise urwid.ExitMainLoop()  
  
edit = MyEdit(u"お名前は? ")  
loop = urwid.MainLoop(urwid.Filler(edit))  
loop.run()  

日本語入力後の画面がこちら。全く問題ありませんね。

ここで、矢印キーを動かして、適当な文字を挿入したり、削除したりしてみましたが、英数、漢字の区別なく正常に処理されました。

(2) npyscreen

同様に、テストしてみます。プログラムは下記。

#!/usr/bin/env python  
# -*- coding: utf-8 -*-  
#  
# s02_npyscreen.py  
#  
import npyscreen  
class TestApp(npyscreen.NPSApp):  
    def main(self):  
        F  = npyscreen.Form(name = "Welcome to Npyscreen",)  
        t  = F.add(npyscreen.TitleText, name = "お名前は?",)  
        F.edit()  
  
if __name__ == "__main__":  
    App = TestApp()  
    App.run()  

表示は出来ましたが、名前を漢字で入力すると、入力フィールドにうまく表示されません。

これはだめですね。npyscreenが、2015年以降メンテされていないことを考えると、今後対応される可能性は低いでしょうから、この段階で評価を終了します。

非常に簡単な評価になってしまいましたが、ここでは

TUIアプリ開発には、”Urwid”を採用する。

と決定しましょう。


Urwidの稼働環境

以下、Urwidの稼働に必要な環境やインストール方法について記述します。

(1) OS

Unix、あるいはそれの疑似環境で動作します。Linuxであれば、どのディストリビューションでも問題はないでしょう。

注意点として、Windows用に配布されているPythonでは、Urwidは動かないということが挙げられます。「NameError: name ‘fcntl’ is not defined」というエラーで終了してしまいます。

Windowsでの動作には、Cygwin、あるいはWSL(Windows10 64ビットのみ)上でPythonをインストールする必要があります。

(2) Pythonのバージョン

Pythonのバージョンは、Urwidがサポートしているバージョンとします。
UrwidのRequirementsには、「Python 2.7, 3.5+ or PyPy」と書いてありますから、これを対象としましょう。

プログラム開発は、Python3.8.5で行いますが、python2.7でも検証していきます。したがって、バージョン限定の断り書きがない限り、ほとんどのプログラムはpython2.7でも動作します。

ただ、今後の記事では、python3ベースに合わせて、Python起動コマンドを”python3”、pipを”pip3”と記述していきます。

(3) Urwidのインストール

pipでインストールするのが一番簡単です。

pip3 install urwid  

このサイトから、ソースを入手しても良いでしょう。


ソースコードについて

GitHubに登録しました。今回のコードは、Section02となります。