##はじめに
Pythonコミニティー「みんなのPython勉強会」の発表で、PySimpleGUIの紹介があった。
PythonのスクリプトにGUIをつける方法
これまで、何とかGUIをTKを使って(あまりちゃんと理解せず)に作っていました。私にとっては、このライブラリーはとても分かりやすいものでした。
試しに使ってみたくなったので、例題としてQRコードを作成するGUIを作ってみました。
PySimpleGUIの説明は、こちらを参照してください。
Tkinterを使うのであればPySimpleGUIを使ってみたらという話
Pythonでデスクトップアプリを簡単に作る方法
PySimpleGUI
##環境
Win10Pro
Anaconda
Python3.7
インストールモジュール
qrcode <--QRコード作成モジュール、PILベース
PySimpleGUI
公式では、pipでのインストールが書いてありますが、
両モジュールともにcondaでインストールできます。
(condaでは、なるべくpipでインストールしない方が良いため。)
conda install -c conda-forge qrcode pysimplegui
QRコード作成GUIその1
pysimpleguiのImage関数の内容をアップデートしてQRを表示するやり方。
import PySimpleGUI as sg
import qrcode as qr
sg.theme('Light Blue 2')
def qrmaker(code):
qr_img = qr.make(str(code))
qr_img.save('temp.png',format="png")
return qr_img
image_init = r'./logo.png' #<--動かすときはこのコードの下にある画像をこの名前で保存してください。
layout = [[sg.Text('Data', size=(8, 1)),sg.Input(key='-qr_data-')],
[sg.Submit()],
[sg.Text('Save Name', size=(8, 1)),sg.Input(key='-qr_name-')],
[sg.Button('Save'), sg.Cancel()],
[sg.Image(image_init,key='-qrimg-')]
]
window = sg.Window('QR code', layout)
while True:
event, values = window.read()
# None -> Windowが閉じられているかどうか
# if event is None or event == 'Cancel': と下のj条件文は同じ
if event in (None, 'Cancel'):
break
elif event in 'Submit':
print('QR code Text: {}'.format(values['-qr_data-']))
qr_img= qrmaker(values['-qr_data-'])
#sg.Imageのアップデートで表示する。
#update()の中は、ファイル名でないとエラーになったので、tempという名のファイルを作成しています。
window['-qrimg-'].update('temp.png')
elif event in 'Save':
save_qr_name= '{}.png'.format(values['-qr_name-'])
qr_img = qrmaker(values['-qr_data-'])
qr_img.save(save_qr_name)
window.close()
上のコードを動かく時は下の画像を'logo.png'として保存して、プログラムと同じホルダーに入れてください。
コードを実行すると
DataとSave Nameを入力してSubmitを押すと
##QRコード作成GUIその2
canvasにQRのイメージを表示させる方法。
import PySimpleGUI as sg
import qrcode as qr
from PIL import Image, ImageTk
sg.theme('Light Blue 2')
def qrmaker(code):
qr_img = qr.make(str(code))
# qr_img.save('temp.png',format="png")
return qr_img
image_init = r'./logo.png'
CANVAS_X = 300
CANVAS_Y = 300
layout = [[sg.Text('Data', size=(8, 1)),sg.Input(key='-qr_data-')],
[sg.Submit()],
[sg.Text('Save Name', size=(8, 1)),sg.Input(key='-qr_name-')],
[sg.Button('Save'), sg.Cancel()],
[sg.Canvas(size=(CANVAS_X, CANVAS_Y), background_color='white', key= '-canvas-')],
]
window = sg.Window('QR code', layout)
canvas = window['-canvas-']
while True:
event, values = window.read()
if event in (None, 'Cancel'):
break
elif event in 'Submit':
print('QR code Text: {}'.format(values['-qr_data-']))
qr_img = qrmaker(values['-qr_data-'])
#TKのCanvasと同じ。PILのイメージをTKに変換しています。
image_tk = ImageTk.PhotoImage(qr_img)
canvas.TKCanvas.create_image(CANVAS_X / 2, CANVAS_Y / 2, image=image_tk)
elif event in 'Save':
save_qr_name= '{}.png'.format(values['-qr_name-'])
qr_img = qrmaker(values['-qr_data-'])
qr_img.save(save_qr_name)
window.close()
##TKで書いた場合(参考)
import tkinter as tk
import tkinter.filedialog as fd
from PIL import ImageTk
import qrcode as qr
base = tk.Tk()
base.title('QRcode Generator')
input_area = tk.Frame(base, relief=tk.RAISED, bd=2)
image_area = tk.Frame(base, relief=tk.SUNKEN, bd=2)
# qrcodeにする文字列を保持する変数
encode_text = tk.StringVar()
entry = tk.Entry(input_area, textvariable=encode_text).pack(side=tk.LEFT)
# qr_codeを表示するためのlabel
qr_label = tk.Label(image_area)
def qr_generate():
qr_label.qr_img = qr.make(encode_text.get())
img_width, img_height = qr_label.qr_img.size
# ImageTkフォーマットへ変換
qr_label.tk_img = ImageTk.PhotoImage(qr_label.qr_img)
qr_label.config(image=qr_label.tk_img, width=img_width, height=img_height)
qr_label.pack()
# qrcodeを生成する処理を呼ぶボタン
encode_button = tk.Button(input_area, text='QRcode!', command=qr_generate).pack(side=tk.LEFT)
# フレームを描画
input_area.pack(pady=5)
image_area.pack(padx=3, pady=1)
# 保存メニュー
def save():
filename = fd.asksaveasfilename(title='名前をつけて保存する', initialfile='qrcode.png')
if filename and hasattr(qr_label, 'qr_img'):
qr_label.qr_img.save(filename)
# 終了メニュー
def exit():
base.destroy()
# メニュー画面作成
menubar = tk.Menu(base)
filemenu = tk.Menu(menubar)
menubar.add_cascade(label='File', menu=filemenu)
filemenu.add_command(label='save', command=save)
filemenu.add_separator()
filemenu.add_command(label='exit', command=exit)
base.config(menu=menubar)
base.mainloop()
##まとめ
このモジュールを使えば本当にGUIが簡単に作れます。
デモプログラムもいろいろと掲載されているので、組み合わせて簡単なGUIを作ってみるのもよいと思います。
PySimpleGUI/DemoPrograms