🍍
FreeSimpleGUIの使い方・クイックスタートガイド
最近、AI開発(特にRAG)でローカル用のGUIアプリを作る機会がありました。
その際、PySimpleGUIとFreeSimpleGUIを比較したので、共有します。
このサンプルコードをベースにすると、簡単な入力フォームや確認ダイアログを作れます。
PythonスクリプトをサクッとGUI化したいときに便利です。
もしご参考になれば、うれしく思います!
PySimpleGUIではなくFreeSimpleGUIがいい理由
- PySimpleGUIは、バージョン5から有償化
- 個人利用は無料
- Tkinterより楽
- FreeSimpleGUIは商用でも無償
- FreeSimpleGUIへの移行は、ライブラリのインストールと、コードのimport文の修正のみ
インストール&インポート
- インストール:
pip install freesimplegui
- インポート:
import FreeSimpleGUI as sg
最小構成のサンプルコード例
以下は、入力フォーム+ボタンの簡単なサンプルです。よく使うパーツを詰め込んでみました。
import FreeSimpleGUI as sg # FreeSimpleGUIライブラリをインポート
sg.theme('DarkAmber') # デザインテーマを設定
# ウィジェットをリストのリストで配置
layout = [
[sg.Text('送信された値をポップアップ表示します。', size=(30, 1), key='-TEXT-')], # テキストを表示(30文字, 1行)
[sg.Input('デフォルトテキスト', key='-INPUT-')], # テキスト入力欄 keyでウィジェットに名前を付与
[sg.Button('送信', key='-SUBMIT-'), sg.Button('終了', key='-EXIT-')] # アクションをトリガーするボタンを並列に配置
]
window = sg.Window('サンプル', layout) # ウィンドウを作成
while True:
event, values = window.read() # イベント源の文字列と各ウィジェットの辞書
if event == sg.WIN_CLOSED or event == '-EXIT-': # ×ボタン or 終了ボタン押下で無限ループを抜ける
break
if event == '-SUBMIT-': # 送信ボタン押下でポップアップ表示
sg.popup(values['-INPUT-'])
window['-TEXT-'].update("ポップアップを表示しました。") # テキスト更新
window['-SUBMIT-'].update("完了", disabled=True) # ボタンを「送信」→「完了」に変え、無効化
window['-INPUT-'].update(disabled=True) # インプットを無効化
window.close() # ウィンドウを閉じる
サンプルコード解説
sg.theme('SystemDefault')
- layoutの定義(2次元リスト):
layout = [[]]
- 各リストはウィジェット
- 各ウィジェットには識別子(
key
)をstring
で指定する
- windowの作成:
window
=
sg.window('タイトル', layout)
- 無限ループ
- 始点:
while True:
-
if event == sg.WIN_CLOSED or event=='-EXIT-':
break
-
event, values = window.read()
- event(string):無限ループの中で今発生したイベントの識別子を一つだけもつ
- values(辞書): すべてのウィジェットの現在の値を識別子で管理
-
if event == 識別子 :
- イベント発生時の処理:例)
window['識別子'].updata()
(ウィジェットの更新)など
- イベント発生時の処理:例)
- 始点:
window.close()
サンプルコードでは触れませんでしたが、[sg.Multiline(size=(80, 30), key='-SHOW_RESULT-')]
なんかも便利です。テーマはDarkAmber
以外にも、SystemDefault
やHotDogStand
など何種類かあります。
補足
個人的に練習で書いたWikiPedia APIをGUIから叩くサンプルコードも、念のため掲載しておきますね。ご参考までに...。
import FreeSimpleGUI as sg
import wikipediaapi
def fetch_wiki_data(term: str) -> dict | None:
"""
指定された用語(キーワード)の情報をWikipediaから取得する関数
成功した場合は情報の辞書(wiki_page_data)を返す。失敗した場合はNoneを返す
:param term: 調査したい用語
:return wiki_page_data: Wikipediaから取得した情報の辞書
"""
print(f"Wiikipediaに接続中...")
wiki_wiki = wikipediaapi.Wikipedia(
language = "ja",
user_agent = "search_wiki(Contact: t.facilita@gmail.com)"
)
# 指定された用語のページオブジェクトを取得
wiki_page = wiki_wiki.page(term)
# 用語がWikipediaに存在しなければNoneを返す
if not wiki_page.exists():
print(f"Wikipediaに{term}は存在せず。")
return None
print(f"{term}の情報を集めています...。")
# 取得した情報を辞書にまとめる
wiki_page_data = {
"title": wiki_page.title,
"url": wiki_page.fullurl,
"summary": wiki_page.summary,
"full_text": wiki_page.text
}
return wiki_page_data
# テーマをセットする
sg.theme("DarkAmber")
# リスト in リストでレイアウトを定義する(keyはウィジェット名)
layout = [
[sg.Text('FreeSimpleGUI入門', size=(30, 1), font=('Helvetica', 25))],
[sg.Text('検索語:'), sg.InputText(key='-INPUT_KEYWORD-', size=(40,1))],
[sg.Button('1. 用語を検索', key='-SEARCH_WIKI-')],
# 取得したデータを表示するための専用ディスプレイ
[sg.Multiline(size=(80, 20), key='-OUTPUT-', disabled=True)],
[sg.Button('サマリー表示', key='-SHOW_SUMMARY-', disabled=True), sg.Button('全文表示', key='-SHOW_FULLTEXT-', disabled=True)],
[sg.Button('終了', key='-EXIT_BUTTON-')]
]
# Windowの作成
window = sg.Window('Wiki検索', layout)
# --- イベントループ ---
wiki_data = None # 取得したデータを保存しておくための変数
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == '-EXIT_BUTTON-':
break
# --- ステップ1:API呼び出し---
if event == '-SEARCH_WIKI-':
term = values['-INPUT_KEYWORD-']
if not term:
sg.popup_error('検索語が入力されてないわよ!')
continue
# フィードバック
window['-OUTPUT-'].update("Wikipediaに接続中... ターゲットを捜索...")
window.refresh()
# API呼び出し
wiki_data = fetch_wiki_data(term)
if wiki_data:
# 成功したら
window['-OUTPUT-'].update(f"【{wiki_data['title']}】の情報を取得しました。\n\n" + wiki_data['summary'])
window['-SHOW_SUMMARY-'].update(disabled=False)
window['-SHOW_FULLTEXT-'].update(disabled=False)
else:
# 失敗したら
sg.popup_error(f"「{term}」は見つからなかったわ。")
wiki_data = None # データ変数をクリア
window['-SHOW_SUMMARY-'].update(disabled=True)
window['-SHOW_FULLTEXT-'].update(disabled=True)
# --- ステップ2:表示切替 ---
# SEARCH_WIKIが成功して、wiki_dataにデータがある時だけ、これらのボタンは意味を持つ
if event == '-SHOW_SUMMARY-':
if wiki_data:
window['-OUTPUT-'].update(wiki_data['summary'])
if event == '-SHOW_FULLTEXT-':
if wiki_data:
window['-OUTPUT-'].update(wiki_data['full_text'])
window.close()
Discussion