(2020-05-11 初稿 - 2021-05-12 転記・修正 )
はじめに
python でユーザからGUI で入力を得るためには、tkinter のsimpledialogを用いると簡単である。 simpledialogは、入力が必要な場面のみダイアログが出るので、筆者のようにCUI をメインに作っている者にはありがたい。 以下は、参考サイト。
しかし、ユーザーから複数の入力を得たい場合は、simpledialog では何回も入力、改行を繰り返すことになってしまう。
そこで、シンプルで複数の入力が可能なダイアログを自作することにした。 もちろん、CUI 好きな筆者なので、今回のスクリプト も一時的なGUI の利用で、ユーザからの入力値を得たらすぐにGUI を終了するものにした。
ところが、自作してみると、入力値を得ることが簡単ではなかった。 一つの解としては、入力値を受け取る変数をグローバル変数 にするというのがある。
以下、参考サイト。
いろいろと試していると、グローバルな変数を使わなくても入力値を得ることができたので、備忘録としてメモを残す。
前提条件が多く前置きが長くなったが、今回作成したスクリプト は、ディレクト リ名(dirname)とファイル名(fname)の2つ値を入力するダイアログである。
(2020-05-12 追記) 別の複数のtkを利用するスクリプト を作成したところ、ウィンドウが消えない現象がありプログラムを変更した。
【補足】 root.withdraw() で ウィンドウを消した状態に root.deiconfy() で ウィンドウを表示
root.quit() guitした後のコードも実行 root.destroy() destroy後のコードは実行されない
#!/usr/bin/env python3
#coding: UTF-8
import sys
import tkinter
def ask_df():
root = tkinter .Tk()
root.withdraw() # 2020-05-12 追記
root.title("Next Entry")
root.geometry("400x120")
# function
def ok_get(event):
root.quit()
#ラベル
label1 = tkinter .Label(text='Directory:')
label2 = tkinter .Label(text='Filename:')
label1.place(x = 20, y = 20)
label2.place(x = 20, y = 50)
#エントリー
editbox1 = tkinter .Entry(width=40)
editbox1.insert(tkinter .END,"Directory Name")
editbox1.place(x=100, y=20)
editbox2 = tkinter .Entry(width=40)
editbox2.insert(tkinter .END,"File Name")
editbox2.place(x=100, y=50)
#ボタン
button1 = tkinter .Button(text='OK')
button1.bind("<Button-1>", ok_get)
button1.place(x=300, y=80)
# Enter でも OK
root.bind('<Return>', ok_get)
root.deiconfy() # 2020-05-12 追記
root.mainloop()
root.withdraw() # 2020-05-12 追記
return editbox1.get(), editbox2.get() # mainloop終了後 値return
if __name__ == "__main__":
dir, fname = ask_df()
print("Dirname:", dir)
print("Filename:", fname)
作成したダイアログ
他のサイトに入力をクリアする方法の記載があったので、参考までに上記スクリプト に加えてみた。 いろいろなオプションやボタンをつける際の参考に。
#!/usr/bin/env python3
#coding: UTF-8
import sys
import tkinter
def ask_df():
root = tkinter .Tk()
root.withdraw() # 2020-05-12 追記
root.title("Next Entry")
root.geometry("400x120")
# function
def deletevalue(event):
#エントリーの中身を削除
editbox1.delete(0, tkinter .END)
editbox2.delete(0, tkinter .END)
def ok_get(event):
root.quit()
#ラベル
label1 = tkinter .Label(text='Directory:')
label2 = tkinter .Label(text='Filename:')
label1.place(x = 20, y = 20)
label2.place(x = 20, y = 50)
#エントリー
editbox1 = tkinter .Entry(width=40)
editbox1.insert(tkinter .END,"Directory Name")
editbox1.place(x=100, y=20)
editbox2 = tkinter .Entry(width=40)
editbox2.insert(tkinter .END,"File Name")
editbox2.place(x=100, y=50)
#ボタン
button1 = tkinter .Button(text='OK')
button1.bind("<Button-1>", ok_get)
button1.place(x=300, y=80)
button2 = tkinter .Button(text='Clear')
button2.bind("<Button-1>", deletevalue)
button2.place(x=200, y=80)
# Enter でも OK
root.bind('<Return>', ok_get)
root.deiconfy() # 2020-05-12 追記
root.mainloop()
root.withdraw() # 2020-05-12 追記
return editbox1.get(), editbox2.get()
if __name__ == "__main__":
dir, fname = ask_df()
print("Dirname:", dir)
print("Filename:", fname)
作成したボタン付きのダイアログ
おわりに
筆者は、python もtkinter もど素人だが、使って覚えれば良いかなと考えている。 さらに、良い方法があったら、gmail のhymd3あてまで、教えてください。
関連ページ