[解決済み] tkinter の Entry ウィジェットの内容を対話的に検証する
質問
tkinterのコンテンツを対話的に検証するために推奨されるテクニックは何ですか?
Entry
ウィジェットでインタラクティブにコンテンツを検証するために推奨されるテクニックは何ですか?
を使用することについての投稿を読みました。
validate=True
と
validatecommand=command
を指定するとクリアされてしまうので、これらの機能は制限されているようです。
validatecommand
コマンドが
Entry
ウィジェットの値を更新します。
この振る舞いを考えると
KeyPress
,
Cut
そして
Paste
イベントを監視・更新し
Entry
ウィジェットの値を監視・更新するのですか?(そして、私が見逃しているかもしれない他の関連するイベント?)
あるいは、インタラクティブなバリデーションを完全に忘れて
FocusOut
イベントでのみ検証すべきでしょうか?
どのように解決するのですか?
正解は
validatecommand
属性を使うことです。残念ながら、この機能はTkの世界では十分に文書化されていますが、Tkinterの世界ではひどく文書化されていません。ドキュメントが不十分でも、バインディングやトレース変数に頼らずに検証を行ったり、検証手順の中からウィジェットを修正したりするために必要なものはすべて揃っています。
トリックは、Tkinterがvalidateコマンドに特別な値を渡すことができることを知っていることです。これらの値は、データが有効かどうかを決定するために知る必要のあるすべての情報を提供します: 編集前の値、編集が有効である場合の編集後の値、および他のいくつかの情報です。しかし、これらを使用するには、これらの情報をvalidateコマンドに渡すために、ちょっとした魔術を使う必要があります。
注意: バリデーションコマンドは、以下のどちらかを返すことが重要です。
True
または
False
. それ以外の場合は、ウィジェットのバリデーションがオフになります。
ここでは、小文字のみを許可する例を示します。また、説明のためにすべての特殊な値の値を表示しています。これらはすべて必要ではありません。1つか2つ以上必要になることはほとんどありません。
import tkinter as tk # python 3.x
# import Tkinter as tk # python 2.x
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
# valid percent substitutions (from the Tk entry man page)
# note: you only have to register the ones you need; this
# example registers them all for illustrative purposes
#
# %d = Type of action (1=insert, 0=delete, -1 for others)
# %i = index of char string to be inserted/deleted, or -1
# %P = value of the entry if the edit is allowed
# %s = value of entry prior to editing
# %S = the text string being inserted or deleted, if any
# %v = the type of validation that is currently set
# %V = the type of validation that triggered the callback
# (key, focusin, focusout, forced)
# %W = the tk name of the widget
vcmd = (self.register(self.onValidate),
'%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
self.entry = tk.Entry(self, validate="key", validatecommand=vcmd)
self.text = tk.Text(self, height=10, width=40)
self.entry.pack(side="top", fill="x")
self.text.pack(side="bottom", fill="both", expand=True)
def onValidate(self, d, i, P, s, S, v, V, W):
self.text.delete("1.0", "end")
self.text.insert("end","OnValidate:\n")
self.text.insert("end","d='%s'\n" % d)
self.text.insert("end","i='%s'\n" % i)
self.text.insert("end","P='%s'\n" % P)
self.text.insert("end","s='%s'\n" % s)
self.text.insert("end","S='%s'\n" % S)
self.text.insert("end","v='%s'\n" % v)
self.text.insert("end","V='%s'\n" % V)
self.text.insert("end","W='%s'\n" % W)
# Disallow anything but lowercase letters
if S == S.lower():
return True
else:
self.bell()
return False
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
を呼び出したときにボンネットの下で何が起こるかについての詳細は、 この章で説明します。
register
メソッドを呼び出したときに起こることについては
なぜtkinterの入力検証ではregister()を呼び出す必要があるのですか?
標準的なドキュメントは Tcl/Tk Entry man pageのValidationセクションを参照してください。
関連
-
[解決済み] 前月の日時オブジェクトを返す
-
[解決済み] データフレームをソートした後にインデックスを更新する
-
[解決済み] PythonからSMTPを使用してメールを送信する
-
[解決済み] 値で列挙名を取得する [重複]。
-
[解決済み] python-requests モジュールからのすべてのリクエストをログに記録します。
-
[解決済み] スペースがないテキストを単語のリストに分割する方法
-
[解決済み] tensorflowのCPUのみのインストールでダイナミックライブラリ 'cudart64_101.dll' を読み込めなかった
-
[解決済み] subprocess.run()の出力を抑制またはキャプチャするには?
-
[解決済み] Django で全てのリクエストヘッダを取得するにはどうすれば良いですか?
-
[解決済み] Pythonの文字列の前にあるbという接頭辞は何を意味するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Pythonでコード行間にかかる時間を測定するには?
-
[解決済み] Djangoで2つの日付の間を選択する
-
[解決済み] DataFrameに日付間の日数カラムを追加する pandas
-
[解決済み] Django で全てのリクエストヘッダを取得するにはどうすれば良いですか?
-
[解決済み] PyQtアプリケーションのスレッド化。QtスレッドとPythonスレッドのどちらを使うか?
-
[解決済み] if 節の終了方法
-
[解決済み] Pythonの文字列書式をリストで使う
-
[解決済み] 認証プラグイン 'caching_sha2_password' はサポートされていません。
-
[解決済み] Python の sorted() はどのようなアルゴリズムを使っているのですか?重複
-
[解決済み] Alembicアップグレードスクリプトでインサートやアップデートを実行するにはどうすればよいですか?