質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Q&A

解決済

1回答

3353閲覧

[Python3] tkinter, テキストボックス内の文字入力規制に関して

3265462164

総合スコア67

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

0グッド

2クリップ

投稿2020/04/02 00:38

■ やりたいこと

作成した入力ボックス内で、+30.00 ~ -60.00 以外の数値が入力された場合はエラーを表示させたい。

記述方法ご存知の方いたらご教授いただけますでしょうか。

python3

1 2from tkinter import * 3from tkinter import ttk 4 5root = Tk() 6root.title("入力制限") 7root.geometry("300x100+40+40") 8 9 10label1 = ttk.Label(text='test', padding=10) 11label1.pack(fill = 'x', padx=50, pady=0) 12entry1 = ttk.Entry(width=50) 13entry1.pack(fill = 'x', padx=50, pady=0) 14

何卒よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

tkinterのEntryには入力された文字列の検証を行う validatecommand (vcmd) という仕組みがありますので、これを使用するのはどうでしょうか。
(validatecommandを使用する場合、エラーが起きるのではなく単に入力できなくなります)

https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/entry-validation.html

下記は正規表現にて入力のフォーマットと、数値の範囲を調べて、エラーの場合は入力できないようにしております。

Python

1from tkinter import * 2from tkinter import ttk 3import re 4 5# 入力した値をチェックする関数 6#(OKの場合はTrue,NGの場合はFalseを返す) 7def validate_input(val): 8 # 未入力状態はOK 9 if val is '': 10 return True 11 # 下記のフォーマットに沿っており、なおかつ -60.0~20.0の範囲はOK 12 fmt = '^[+-]?[0-9]{1,2}(?:.[0-9]{,2})?$' 13 if re.match(fmt, val) and (float(val) >= -60.) and (float(val) <= 20.): 14 return True 15 # それ以外はNG 16 return False 17 18root = Tk() 19root.title("入力制限") 20root.geometry("300x100+40+40") 21label1 = ttk.Label(root, text='test', padding=10) 22label1.pack(fill = 'x', padx=50, pady=0) 23validate = root.register(validate_input) 24entry1 = ttk.Entry(root, width=50, validate="key", validatecommand=(validate, "%P")) 25entry1.pack(fill = 'x', padx=50, pady=0) 26 27root.mainloop()

【追記】
エラーを表記するバージョンも書いてみましたので一応
入力検証では数値表記かのみをチェックして、入力変更通知で範囲確認&エラー表示をおこなっております。

Python

1from tkinter import * 2from tkinter import ttk 3import re 4 5# 入力した値を検証する関数(少数表記以外の入力不可) 6def validate_input(val): 7 # 未入力状態かフォーマットに沿っていたらOK 8 fmt = '^[+-]?\d+(?:.\d*)?$' 9 if (val == '') or re.match(fmt, val): 10 return True 11 return False 12 13# 入力した値が変更した場合呼ばれる関数 14# こちらで範囲を検証してエラー表記 15def change_entry(): 16 if entry_val.get() == '': 17 err_label.config(text='値を入力してください') 18 elif (float(entry_val.get()) < -60.) or (float(entry_val.get()) > 30.): 19 err_label.config(text='範囲エラー(-60.~30)') 20 else: 21 err_label.config(text='') 22 23root = Tk() 24root.title("入力制限") 25root.geometry("300x100+40+40") 26label1 = ttk.Label(root, text='test', padding=10) 27label1.pack(fill = 'x', padx=50, pady=0) 28validate = root.register(validate_input) 29entry_val = StringVar() 30entry_val.trace("w", lambda *arg: change_entry()) 31entry1 = ttk.Entry(root, width=50, validate="key", validatecommand=(validate, "%P"), textvariable=entry_val) 32entry1.pack(fill = 'x', padx=50, pady=0) 33err_label = Label(root, foreground='red') 34err_label.pack() 35 36root.mainloop()

【コメントを受けて再度追記】
入力過程で '-' のみ、'+' のみの入力値になるので、それも validation で許可する必用がありそう。
(正規表現でやろうと思ったけど面倒だったので、単純に条件文に追加しました)

Error表示版での修正は以下のようになりますね。

Python

1# 入力した値を検証する関数(少数表記以外の入力不可) 2def validate_input(val): 3 # 未入力状態かフォーマットに沿っていたらOK 4 fmt = '^[+-]?\d+(?:.\d*)?$' 5 if (val == '') or (val == '+') or (val == '-') or re.match(fmt, val): 6 return True 7 return False 8 9# 入力した値が変更した場合呼ばれる関数 10# こちらで範囲を検証してエラー表記 11def change_entry(): 12 if entry_val.get() == '': 13 err_label.config(text='値を入力してください') 14 elif (entry_val.get() == '+') or (entry_val.get() == '-'): 15 # '+'のみや'-'のみの時は入力中とみなして何もしない 16 pass 17 elif (float(entry_val.get()) < -60.) or (float(entry_val.get()) > 30.): 18 err_label.config(text='範囲エラー(-60.~30)') 19 else: 20 err_label.config(text='')

投稿2020/04/02 01:40

編集2020/04/02 04:36
magichan

総合スコア15898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

magichan

2020/04/02 01:49

スミマセン範囲間違ってました・・・ 最大値は20ではなく30ですね
magichan

2020/04/02 02:47

エラーを表記するバージョンも追加しておきました。
3265462164

2020/04/02 03:45

magichanさん、ありがとうござました! 想定以上の動作です。 validatecommand、非常に参考になりました。 ただ、一点ですが、正の数値は入力できたのですが、 負の数値は入力できませんでした。 コードを見ているのですが見当がつかず。。 お手すきの際にご確認いただけたら幸いです。
magichan

2020/04/02 04:20

あれ?出来ませんか? 1点心当たりがあるとすると、現状の Validation で使用している正規表現が、'+' のみや '-' のみの文字列を許可していないので、数値を入れてから戻って '-' や '+' をつけなければ入力できませんので、このあたりを直す必用がありますね。
magichan

2020/04/02 04:36

回答に修正部を記述しました
teamikl

2020/04/02 04:38

入力が "-" だけの時の扱いですよね。(1文字目の入力) 数字を入力してからカーソルを戻して"-"を入れると入力可。 書式としては数値に変換できないので正しくないけど、 入力の流れとしては頭から入力するのは自然なので、扱えないと困るケース。 暫定的な対応だと入力の許容は 正規表現の\d+ => \d* で出来そうですが、 値を読み出しの際には注意。(範囲チェック時 float("-") となってエラー) StringVar -> DoubleVar にすると float() を省けるかもと思ったけど DoubleVar でも "-" だけの値を読みだそうとした時はエラーになります。
magichan

2020/04/02 04:38

あとボタンなどを配置している場合は、 change_entry() 関数内でボタンの有効・無効を制御するともう少し使い勝手が上がると思います。
magichan

2020/04/02 04:42 編集

@teamiklさん 私も \d+ を \d* にしようと思ったのですが、今度  '-.' というケースに対応出来なくて面倒になったので諦めました(スミマセン)
3265462164

2020/04/02 04:46

ご回答ありがとうございました! teamiklさんのおっしゃる通りで、マイナスを入力する際に、"-"から入力すると無効でしたが、 数値を入れた後にカーソルを戻して入力すれば問題ありませんでした。 再度magichanさんに記載していただいたコードで問題なく動作しております。 本当にありがとうございました!
teamikl

2020/04/02 04:54

@magichanさん なるほど、別の文字に引っかかるのですね。 私もtrace()の使い方辺り参考になりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問