PySimpleGUI の Widget 演習
楽しみながら覚えられるよう、Widget をネタに自分が使いたい必要な要素に絞ってメモ。
“Widget”は”エレメント”と称しても良いようだ。どちらに統一するかは書きながら考えることにした。
画面デザインの基本作法
PySimpleGUI 利用の場合の基本形を覚えよう。VB用語の使用は必要最低限にとどめる
高級言語なので命令文や関数・引数などは平易な英単語がほとんどのため取り組みやすい。
layout や window などは変数(関数?)と呼んで良いのか分からないので、今は要素という呼称にしている。
- ライブラリをインポートし、各種サンプルに従って sg をエイリアス名にする
- アプリのカラーテーマを設定 ※必須ではない
- layout 内にテキストボックスなどのエレメント(要素) を左上から順にコードを書いて代入
レイアウト全体を角括弧( [ ] )でくくり、エレメントを同様に [ ] で入れ子にして配置
各エレメントの書き方は後述 ※[ ] でくくったエレメント間はカンマで区切る - window要素 にプロパティを設定 ※設定を省略しても自動でサイズ調整される
- while True: で無限ループを作り、window.read() 関数によってインタラクティブウィンドウ(常時更新状態)にする
ループ内に、ウィンドウそのものの上書きによる操作結果の処理を書く
※これをやらないと、操作結果が画面上に反映されない
※入力項目がない画面ではループ処理は不要
簡単な画面で練習
最初は、テキストボックスに入力された値を実行ボタンが押されたら、入力された文字列を連結して結果を表示する単純なサンプル。ひねくれ者は 「Hallow World!」なんかやらないのだ。
もちろん、これだけでもけっこうつまづいた・・・(;`ー´)
VSCode(Visual Studio Code)で書いたプログラムの全容。
import PySimpleGUI as sg # PySimpleGUI ライブラリの利用を宣言。公式サンプルにならって別名を SG とする
sg.theme('BluePurple') # テーマの設定 なくても動作するなくても
# 画面内のWidgetを左上から順に配置
layout = [
[sg.Text("お名前どうぞ")],
[sg.Text('姓'),sg.Input(key='姓',size=(10,2)), ラベルと入力用テキストボックス
sg.Text('名'),sg.Input(key='名',size=(10,2))],
[sg.Text("入力結果は : "), sg.Text(key='姓名',size=(25,1))],
[sg.Button('実行'), sg.Button('閉じる')],
]
window = sg.Window('Widget 演習中', layout,size=(600,400)) # ウィンドウのタイトルとサイズを設定
while True: # ウィンドウを表示し続ける
event, values = window.read() 画面更新とイベント、キー取得
print(event, values)
if event == sg.WIN_CLOSED or event == '閉じる':
break
if event == '実行':
# テキストボックスに結果表示
window['姓名'].update(values['姓']+values['名'])
window.close()
最初は超基本の定型プログラムスタイルとして覚えておき、順次発展させていくようにする。
ネット上のサンプルコードでは命令や引数など例外なく英文小文字表記になっている。
自分はプロになるつもりはないので、入力効率は二の次で、使えそうな部分は遠慮なく日本語使いまくり方針である。圧倒的に読みやすさが違うから。
引用符もシングルでも二重でも問題なさそうなので、文字列表示には二重引用符を使っている。
エレメントの基本
初学なので覚えるべき用語と作法が多いが、これは身体で覚えるしかない。
Text : テキストボックスの表示
書式は ライブラリ名.[Text(“表示文字列”,引数,引数,・・・)]
text と書くとエラーになるので注意。
最初のレイアウト要素 [sg.Text(“お名前どうぞ”)], は、第一引数に文字列を書くとそのままラベルとして表示される。処理結果の表示目的では [sg.Text(“入力結果は : “), sg.Text(key=’姓名’,size=(25,1))] とする。
角括弧内でエレメントを複数書くと横並びになる。二番目エレメントのように第一引数を書かないと何も表示しないが、ユーザーの入力結果を表示するためのエレメントなのでそれで良い。
引数に順序は関係しないので key=’姓名’ ,size=(25,1) のようにカンマでつないで列挙する。key= は、エレメントキーまたはエレメントID(と呼んで良い?)の指定。
処理結果を出力するエレメントで、値の取得元(存在位置)を特定するため必須の引数である。
layout 内でユニーク値でなければならない。数値でも文字列でも構わないようだ。
値を参照するには、無限ループ内の window[‘姓名’].update(values[‘姓’]+values[‘名’]) のようになる。
Input : 入力用テキストボックス
書式は ライブラリ名.[Input(key=キー名,引数,引数,・・・)]
テキストボックスを配置して、ユーザーが文字列や数値を入力出来るようにする。
テキストボックスのオプション引数
size=(数値,数値)
テキストボックスの幅と高さを半角文字数で指定する。省略するとウィンドウ幅に対応して表示される。
その他、フォント指定など多彩なオプション機能は公式サイトのページを参照。
注意点
- 本サンプルでは変数を使っていないが、変数宣言や型指定が不要な仕様のもよう
- コード内で命令語は大文字と小文字が厳密に区分されている
例) sg.Text を sg.text と書くのは❌ - オブジェクト変数(?)の sg は SG でも問題なさそう(おそらく他の任意の名前でも可)
- [ ] は段落(?)単位を表すので、Widget を横並びにするには [ ] 内でカンマ区切りして列挙する
- while 文や if 文には終わり命令がないので動作範囲が分かりにくい
- 画面更新のために全要素が常時上書きされるようなので気持ちが悪いが諦めよう
良く考えると、Access のフォームだって、内部では常時表示になってたな・・・ - 条件分岐の case 文に相当する関数もなさそうなので、選択肢の Widget 処理でちょっと不安がある
Widget を増やしていくと膨大な If 文羅列になりそうで気が重い・・・ - VBの With や For each のような便利系構文もなさそうなのでちょっと面倒 ※知らんだけかも
- キーボード操作でのボタンは Enter ではなくスペースキーを使う(引数次第で変更は可能)
初学なのでどうしても説明部分が多くなるが、自分のために頑張って書くことにした。
といいつつ、疲れたので後半部のループ処理についてはまた後日(;`ー´)
コメント