PySimpleGUIというPythonでかんたんにGUIを作れるライブラリを触ってみたので備忘録。
目次
- 目次
- PySimpleGUIとは?
- PySimpleGUIはライセンスが LGPL3.0 なので商用利用などで実行バイナリを配布する場合は注意が必要
- PySimpleGUIで作成したログ表示サンプル
- PySimpleGUIのテーマカラーについて
- FindElementに関するWarning
- Effective Python良かった(余談)
PySimpleGUIとは?
2018年に作成された比較的新しいライブラリで、tkinter, Qt, WxPython, RemiなどのGUIフレームワークを、よりシンプルなインターフェースに変換して利用できるライブラリ。
つまりGUIフレームワークのラッパー的な立ち位置となる。
ラッパーという立ち位置からも想像できるようにPySimpleGUIを使えば、GUIフレームワークを使ってゴリゴリUIを作成するよりもかんたんにGUIが構築できる。またpip経由でインストールが可能、というのも楽なポイント。
勿論、UIを作る用途によっては適さないシーンもあるようなので、作成するUIにそこまでこだわりはなく、ある程度工数をかけずにPythonでGUIを構築したいという用途が一番マッチするような印象。
実際インストールはかんたんで、下記のようにpipインストールし、
pip install pysimplegui
公式ページにある、かんたんなサンプルを入力することで問題なくGUIが立ち上がった。
import PySimpleGUI as sg sg.theme('DarkAmber') # Add a touch of color # All the stuff inside your window. layout = [ [sg.Text('Some text on Row 1')], [sg.Text('Enter something on Row 2'), sg.InputText()], [sg.Button('Ok'), sg.Button('Cancel')] ] # Create the Window window = sg.Window('Window Title', layout) # Event Loop to process "events" and get the "values" of the inputs while True: event, values = window.read() if event == sg.WIN_CLOSED or event == 'Cancel': # if user closes window or clicks cancel break print('You entered ', values[0]) window.close()
なお、筆者の環境はM1 Macであり、Pyenvを用いた上で構築している Python 3.9.6
で動作している。
※m1 macでのpyenv環境構築については下記に書いたので興味ある方はぜひ
GUI周りだし何かしらエラーで立ち上がらないだろうな、と期待していなかったが、いちおう問題なくGUIは立ち上がったので、これは良いかもと思った次第。
PySimpleGUIはライセンスが LGPL3.0 なので商用利用などで実行バイナリを配布する場合は注意が必要
ここで余談を挟むが、最近はVBAからPythonへの移行が増えてきているらしい。
もともとVBAで書かれていた業務アプリをPythonに移植するような感じだ。
そんな流れでかんたんなGUIを構築する際のライブラリとしてPySimpleGUIが用いられている例をいくつか見つけた。
たしかに今回触ってみたが、サクッとGUIを構築できたので、これは便利そうだと思った次第。
ただし注意点があり、PySimpleGUIはライセンスがLGPL3.0のため、例えばPySimpleGUIを含んだ状態で作成した実行バイナリを配布する場合は、ソースコードを公開しなくてはならない点に注意が必要となる。
ソースコード公開を回避するためには下記のような手段を取るなど一応回避手段はあるようだが、一度ここらへんは利用を始める前に検討してみたほうが良いだろう。
(下記の手段を取る場合はユーザのPCにPython環境を構築する必要がある)
なお、実行バイナリを配布して利用してもらいたいケースでは残念ながらPySimpleGUIは使えないので、代替案としてtkinterなどを利用することになるかと思われる。
ちょうど今tkinterを使ったGUIプログラミングについてをあれこれとまとめているので興味ある方はこちらも参照してみてください。
PySimpleGUIで作成したログ表示サンプル
今回はひとまずボタンに対応する処理を動かすのと、処理の中のログを表示する窓を作ってみることにした。
また、ログの内容をクリップボードにコピーする機能と、クリアする機能も合わせてつけてみた。
サンプルのコード量としては大したことないので、たぶん私が浅い知識で解説を挟むよりも、直接コードを見てもらったほうが分かるかと思う。
PySimpleGUIをインストールした環境で、下記のコードをコピペして実行してもらえれば、こんなウィンドウが立ち上がるかと思う。
なお、今回テーマカラーは適用していないが、テーマを指定したい場合は4行目のコメントアウトを外して、対応したカラースキームの文字列を入力すれば適用される。
テーマカラーについては少しだけこのあとに書いている。
import PySimpleGUI as sg # テーマカラー # sg.theme("Default") # メインのコントロールエリア control_layout = [ [sg.Button("Test Log Output")], [sg.Button("Close")] ] # ログの表示・操作エリア log_layout = [ [sg.Button("Copy"), sg.Button("Clear")], [sg.Output(size=(100, 5), key="-OUTPUT-")], ] layout = [ [sg.Frame("Log", log_layout)], [sg.Frame("Main Control", control_layout)] ] # ウィンドウを作成 window = sg.Window("PySimpleGUI Log Sample", layout) # このループ内でイベントと入力値の処理を行う while True: event, values = window.read() # ウィンドウを閉じたときはここの処理が動く if event == sg.WIN_CLOSED: break # Closeボタンを押したときはここの処理が動く # ここではサンプルとして分けているが、上の処理と同じなのでif文はまとめてOK if event == "Close": break if event == "Test Log Output": print("Push [Test Log Output]") if event == "Clear": window.find_element("-OUTPUT-").Update("") if event == "Copy": window.find_element("-OUTPUT-").Widget.clipboard_append(window.find_element("-OUTPUT-").Get()) sg.popup("Log copied to Clipboard.") window.close()
今回、律儀に if
だけで区切って書いているが、elif
などで分岐させてもよいのかもしれないし、実際にそうやってサンプルを書いている方もいたので、それで良い気がする。
実際に起動すると、print
関数で出力されるログがログ出力用エリアに出力されるのが分かると思う。
また、今回
event, values = window.read()
の values
の値を使っていないが、これはまた別にサンプルを書いてみようと思う。
(PySimpleGUIを少しずつ理解していこうと思う)
PySimpleGUIのテーマカラーについて
PySimpleGUIには様々なカラースキームが用意されており、それらの一覧は下記のコードを実行することで確認できる。
import PySimpleGUI as sg sg.theme_previewer()
これを実行すると、下記のようなウィンドウが立ち上がる。
ここで利用したいテーマカラーを sg.theme("利用したいテーマ")
に入力すれば適用される。
FindElementに関するWarning
今回のサンプルを実装する上で下記のようなwarningに遭遇したので、書いておく。
FindElement
という対応するkeyを取得するための関数があるが、これを使うと下記のようなwarningが出る
UserWarning: Use of FindElement is not recommended. Either switch to the recommended window[key] format or the PEP8 compliant find_element warnings.warn('Use of FindElement is not recommended.\nEither switch to the recommended window[key] format\nor the PEP8 compliant find_element', ** Warning - FindElement should not be used to look up elements. window[key] or window.find_element are recommended. **
エラーメッセージの通りで、FindElement
ではなく find_element
を使うことでwarningは消える
下記の通り。
if event == "Clear": window.FindElement("-OUTPUT-").Update("")
下記のようにすることでwarningが消える
if event == "Clear": window.find_element("-OUTPUT-").Update("")
以上のようにまだ少ししか触れていないが、特に面倒なエラーにも遭遇せずに扱えたので、第一印象は良さそう。
引き続き、少しずつ触っていってみようと思う。
Effective Python良かった(余談)
ずっと家で積ん読していた Effective Python
を読んだら、すごくかゆいところに手の届く内容だった。
こういうときPythonだとどう書くのが良いのか?スレッド処理はどうする?などなど、普段からコード書きながら感じていた疑問が、氷が溶けるように本を読み進めていく中で溶けていくのを感じた。
しかも今試しにチェックしてみたら、第2版がでていて、内容をパワーアップしているよう!
個人的に買ってよかったPython本の一つです。