先日、手軽に使えるGUIライブラリ「PySimpeGUI」のバージョン5がリリースされ、それに伴って商用利用が有償化された。個人利用はこれまで通り無償だがライセンス登録が必要になる。そこで、本稿ではPySimpleGUIを使い続ける方法と、互換ライブラリ「TkEasyGUI」に乗り換える方法の二つを紹介する。
簡単GUIライブラリ「PySimpleGUI」について
本連載の109回目でPySimpleGUIの使い方を紹介した。PySimpleGUIは独自のイベントモデルを採用し、二次元リストを使って手軽にGUIを構築できるライブラリだ。
PythonでGUIを持つデスクトップアプリを開発するには、TkinterやPyQtなど、いくつかの選択肢がある。しかし、いずれも本格的なGUIを作るのには向いているが、ちょっとしたツールを素早く作りたい場合に、学習コストの問題や開発が煩雑という問題があった。
しかし、「PythonでGUIアプリを作るのは、なかなか骨が折れる」という常識を打ち破ったのが、PySimpleGUIだ。下記のように、二次元のリストに利用したいGUI部品を配置するだけで、画面を設計できるのが素晴らしいところだ。
import PySimpleGUI as sg
# GUIを定義する --- (*1)
layout = [
[sg.Text("名前を入力してOKボタンを押してください")],
[sg.Input("太郎",key="-name-"), sg.Button("OK")],
]
# ウィンドウを作成する --- (*2)
window = sg.Window("名前", layout)
# イベントを処理 --- (*3)
while True:
# GUIで発生したイベントを一つ読む --- (*4)
event, values = window.read()
if event == sg.WIN_CLOSED: # ウィンドウを閉じた時の処理 --- (*5)
break
if event == "OK": # OKボタンが押された時の処理 --- (*6)
name = values["-name-"]
sg.popup(f"こんにちは、{name}さん")
Pythonパッケージの「PySimpleGUI」をインストールし、実行すると下記のように表示される。(パッケージのインストールについては後述する。)
プログラムを確認してみよう。(*1)の部分で画面を定義している。プログラムの実行画面と、ここで定義した二次元リストを見比べてみよう。なんとなく二次元リストとGUI部品の見た目が一致しているのが分かるだろう。
(*2)でウィンドウを作成して、(*3)以降でボタンを押した時などのイベントを処理する。GUIを持つプログラムでは、ユーザーがボタンを押したり、ウィンドウを閉じたりといったアクションを行うたびに、それをどのように処理するかを、開発者が決めて処理しなくてはいけない。
それで、ウィンドウが表示されている間、繰り返し(*4)にあるように、イベントを取得して、それをどのように処理するかを記述する。(*5)ではウィンドウを閉じた時の処理を記述し、(*6)ではOKボタンが押された時の処理を記述する。
(*6)を見ると分かるように、「OK」ボタンをクリックした時には、「OK」というイベントが発生するようになるので、とても直感的に処理ができる。
このように、PySimpleGUIを使うと、とても簡単に独自のデザインのGUIウィンドウを設計し、処理するプログラムを作成できる。従来のGUIフレームワークでは、独自の配置メソッドを呼び出したり、座標を指定したりと、とても手間がかかるものだった。
PySimpleGUI 5をインストールしよう
先日(2024年2月)に、PySimpleGUI 5が登場したわけだが、これまでと一番大きな違いは商用での利用が有償化されたことだ。それまでオープンソースのライセンスであるLGPLを採用しており、自由に利用できたのだが、バージョン5より、ライセンス形態が一変した。個人利用は引き続き無料だが、その場合も、ライセンス登録が必要になった。ただし、30日間の無料利用期間が設けられている。
これまでPySimpleGUIを使ってきたユーザーは、ライセンス料(1年99米ドル)を払って使い続けるか、PySimpleGUIの互換ライブラリに乗り換えるのかという選択を迫られることになった。
もちろん、上述のように、PySimpleGUIは手軽にGUIを構築できる優秀なライブラリであり、開発者は長年無償でコツコツとサポートを続けてくれていた。これからも継続的なサポートが行われることを期待して、年間ライセンスを払うというのも悪いことではないだろう。
なお、ライセンスの取得ページは、全て英語であるため、本稿では簡単にライセンスの取得方法を紹介する。
最初に、PySimpleGUIのサインアップのページ(こちら - https://www.pysimplegui.com/pricing)にアクセスしよう。そして、個人利用であれば「Hobbyist」を、商用利用であれば「Commercial」を選択しよう。
すると、次のようにアカウントの作成画面になる。フォームに記入して「Register(登録する)」ボタンを押そう。基本的には難しくないが、登録にはGitHub IDが必要になる。GitHubの登録は親切なマニュアルがこちらにあるので参考にしよう。
その後、メールによる認証が行われる。メールに書かれた数字を入力すると、登録が完了する。すると、ライセンスキーが発行されるので保存しておこう。
続いて、PySimpeGUIの最新版をインストールする。ターミナル(WindowsならPowerShel、macOSならターミナル.app)を起動して、以下のコマンドを入力しよう(※Windowsの場合、python3をpythonに)。
python3 -m pip install pysimplegui
その後、本連載の冒頭で紹介したプログラムを「simple.py」という名前で保存して、ターミナルで「python simple.py」を実行しよう。すると次のような画面が表示される。画面下の「I accept the terms...(規約に同意する)」にチェックを入れて「Ok」ボタンをクリックすると、ライセンスキーの入力画面が出るので、上記のライセンスを入力しよう。
互換ライブラリ「TkEasyGUI」について
実際のところ、PySimpleGUIはとても高機能なライブラリだ。幅広い用途に応じた多くのGUI部品が利用できる。とは言え、簡単にGUIアプリを作りたいという用途においては、基本的にボタンやエディタなど、基本的なGUI部品が利用できれば良くて、それほど高機能なGUI部品が必要ない場面もあるだろう。そんな場面では、PySimpleGUIの互換ライブラリも検討できるだろう。
互換ライブラリの筆頭が「TkEasyGUI」というライブラリだ。手前味噌で恐縮ではあるが、筆者がGitHubでオープンソースの形態で開発している。今回のPySimpleGUIの有償化に伴い自作のアプリで採用するのに便利な緩いオープンソースのライセンスMITを採用し、将来にわたってライセンス変更をしないことを謳っている。
完全互換ではないものの、基本的なボタン(Button)やエディタ(Input)、画像表示(Image)や図形描画(Canvas)などのGUI部品を備えており、PySimpleGUIの主要なプロパティを実装している。
TkEasyGUIをインストールするには、ターミナルで以下のコマンドを実行しよう。
python -m pip install tkeasygui
そして、上記のプログラムの一行目にあるimport文を次のように修正しよう。
# import PySimpleGUI as sg
import tkeasygui as sg
これだけの作業で、先ほどのプログラムを同じように動かすことができる。プログラムを動かすには、プログラムを書き換えて保存したら、ターミナルから「python simple.py」と実行しよう。
実行画面を比べてみると分かるのだが、見た目が少しだけ異なるのが分かるだろう。これは、Python標準のGUIツールキットTkinterを素のまま利用しているためだ。しかし、よりOSの挙動に合わせたデザインとなっている。
また、TkEasyGUIをスクラッチから作るのに当たって、PySimpleGUIを利用していて不便だと思う点があったので、互換性を維持しつつもいろいろ改良してみた。
特に、PySimpleGUIではイベントループを記述する際、必ず、ウィンドウを閉じるイベントを定義する必要があったが、TkEasyGUIでは、イベントループを工夫して、次のように「while window.is_alive()」をチェックするだけで良くなるようにしてみた。
以下は、TkEasyGUIでフォルダを選択する画面を作ってみたものだ。
import tkeasygui as sg
# GUIを定義する
layout = [
[sg.Text("フォルダパスを指定してください:")],
[sg.Input("",key="-path-"), sg.FolderBrowse()],
[sg.Checkbox("サブフォルダも含める", key="-sub-")],
[sg.Button("OK")]
]
window = sg.Window("フォルダ選択", layout)
# イベントを処理
while window.is_alive(): # ウィンドウが有効か確認--- (*1)
# イベントを取得
event, values = window.read()
if event == "OK": # OKボタンが押された時の処理
sg.popup(f"次のフォルダを処理します\n{values['-path-']}")
それほど大きな違いはないのだが、(*1)のようにウィンドウが有効かどうかを確認することで、毎回、記述していたウィンドウを閉じるかどうかの判定処理を省けるようにした。
なお、それ以外の部分はPySimpleGUIを使ったことがある人にとってはお馴染みのものだろう。基本的なGUI部品をPySimleGUIと同様に使うことができる。
ちなみに、オープンソースのプロジェクトが有償化される際、よくあるのが、有志が既存のプロジェクトをフォークして(以前のソースコードを元にして)、新しいプロジェクトを立ち上げるというのがある。しかし、PySimpleGUIは有償化に伴いこれまでオープンソースとして公開していたコードの公開を止めて、ソースコードを参照できないようにしてしまった。そこで、互換ライブラリのTkEasyGUIは公開情報だけを元にしつつ、ゼロからライブラリを実装したものだ。