ひゃまだのblog

ひゃまだ(id:hymd3a)の趣味のブログ

python-tkで、Entryから複数の入力値を得るための最低限のスクリプト

(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)

 

f:id:hymd3a:20210512091438p:plain

作成したダイアログ

 

スクリプトの拡張

他のサイトに入力をクリアする方法の記載があったので、参考までに上記スクリプトに加えてみた。
いろいろなオプションやボタンをつける際の参考に。

#!/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)

f:id:hymd3a:20210512093034p:plain

作成したボタン付きのダイアログ

おわりに

筆者は、pythontkinterもど素人だが、使って覚えれば良いかなと考えている。
さらに、良い方法があったら、gmailのhymd3あてまで、教えてください。

関連ページ