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

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

新規登録して質問してみよう
ただいま回答率
85.46%
文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

893閲覧

pythonのentryウェジェットvalidate オプション動作

akiteru

総合スコア18

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/09/25 06:26

前提・実現したいこと

pythonのentryウェジェットで日付入力を作っています。
やりたいことは初期値は「yy/mm/dd」と表示させ、入力は半角数字のみ可、順次入力し、区切り記号「/」の時はこれを生かし次に飛び越す、こんなイメージです。
下記のtest1.pyコードを実行し半角数字チェック部を実行するとチェックは正常に実行されます。この時のprintでの表示部は下記の通りです。
onValidat in
onValidate out
onValidat in
挿入文字列「ラージS=」1 挿入前文字列「スモールs」= 文字位置「i」=0
onValidate out
onValidat in
挿入文字列「ラージS=」2 挿入前文字列「スモールs」=1 文字位置「i」=0
onValidate out
onValidat in
挿入文字列「ラージS=」3 挿入前文字列「スモールs」=12 文字位置「i」=0
onValidate out
onValidat in
挿入文字列「ラージS=」a 挿入前文字列「スモールs」=123 文字位置「i」=0
onValidate out
inValidate in
inValidate out
質問(A)
ここに表視させた「%i」の値は常に0(ゼロ)です。1,2,3の入力で順次入力位
置iは0,1,2と変わらないのでしょうか?「%i」は何を表すのでしょうか?
これに対し日付の初期処理部(2)コメント部分を加えたtest2.pyではprint表示は下記となります。
onValidat in
forcus in 1
onValidate out
inValidate in
forcus in 2
inValidate out
フォーカスインすると1回だけonValidatとinValidateを実行し、その後何を入力してもウェジェットには入力値が表示されますがチェックは実行されません。
質問(B)
チェックが実行されない原因と対策をご教授ください
質問(C)
区切り記号「/」部に入力位置が来た場合強制的にカーソルを「/」の後に
移動させる方法をご教授ください

ここに質問の内容を詳しく書いてください。
(例)PHP(CakePHP)で●●なシステムを作っています。
■■な機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

ソースコ # test1.py # 全半角判定用 import unicodedata import tkinter as tk class Application(tk.Frame): def __init__(self, master = None): super().__init__(master) self.master.title("Entryの作成") # ウィンドウタイトル self.master.geometry("300x100") # ウィンドウサイズ(幅x高さ) validate_command = self.master.register(self.hizuke_onValidate) invalidate_command = self.master.register(self.hizuke_inValidate) self.entry = tk.Entry(self.master, width = 30, validate='all', # 検証をどのタイミングで行うか?を指定します validatecommand = ( validate_command, '%d', # アクションの種類 1:挿入、0:削除、-1:再検証 '%i', # 挿入/削除される文字の位置 挿入/削除されない場合は-1 '%P', # テキスト編集後の文字列 '%s', # テキスト編集前の文字列 '%S', # 挿入/削除される文字列 '%v', # validateオプションで指定した種類 '%V', # 実際に実施されたvalidateの種類 '%W' # Entryウィジェットの名前 ), invalidcommand = ( invalidate_command, '%d', # アクションの種類 1:挿入、0:削除、-1:再検証 '%i', # 挿入/削除される文字の位置 挿入/削除されない場合は-1 '%P', # テキスト編集後の文字列 '%s', # テキスト編集前の文字列 '%S', # 挿入/削除される文字列 '%v', # validateオプションで指定した種類 '%V', # 実際に実施されたvalidateの種類 '%W' # Entryウィジェットの名前 )) self.entry.pack() # 入力値の正否判定関数 def hizuke_onValidate(self, d, i, p, s, S, v, V, W): print("onValidat in") # 入力キー不正のフラッグ(NG時はng=1) ng = 0 # 異常の有った時点で処理するため「break」でループを抜ける for i in range(1): # (2)半角数字以外の時は不可 if V == 'key': # 挿入文字位置i表示 print("挿入文字列「ラージS=」" + S + " 挿入前文字列「スモールs」=" + s + " 文字位置「i」=" + str(i)) if S == "yy/mm/dd": break # 英数半角以外NG if unicodedata.east_asian_width(S) != 'Na': ng = 1 # 数字以外の時は不可 if S.isdecimal() == False: ng = 1 # 半角数字以外時に挿入前表示に戻す if ng == 1: # forループを抜ける break print("onValidate out") # カーソルを指定位置に移動 if ng == 1: return False else: return True # 入力値不適の後処理関数 def hizuke_inValidate(self, d, i, p, s, S, v, V, W): print("inValidate in ") for i in range(1): if V == 'focusin': print("forcus in 2") var = self.entry.get() if len(str.split(var)) == 0: self.entry.insert(0, "yy/mm/dd") break print("inValidate out") if __name__ == "__main__": root = tk.Tk() app = Application(master = root) app.mainloop() #*************************** # test2.py # 全半角判定用 import unicodedata import tkinter as tk class Application(tk.Frame): def __init__(self, master = None): super().__init__(master) self.master.title("Entryの作成") # ウィンドウタイトル self.master.geometry("300x100") # ウィンドウサイズ(幅x高さ) validate_command = self.master.register(self.hizuke_onValidate) invalidate_command = self.master.register(self.hizuke_inValidate) self.entry = tk.Entry(self.master, width = 30, validate='all', # 検証をどのタイミングで行うか?を指定します validatecommand = ( validate_command, '%d', # アクションの種類 1:挿入、0:削除、-1:再検証 '%i', # 挿入/削除される文字の位置 挿入/削除されない場合は-1 '%P', # テキスト編集後の文字列 '%s', # テキスト編集前の文字列 '%S', # 挿入/削除される文字列 '%v', # validateオプションで指定した種類 '%V', # 実際に実施されたvalidateの種類 '%W' # Entryウィジェットの名前 ), invalidcommand = ( invalidate_command, '%d', # アクションの種類 1:挿入、0:削除、-1:再検証 '%i', # 挿入/削除される文字の位置 挿入/削除されない場合は-1 '%P', # テキスト編集後の文字列 '%s', # テキスト編集前の文字列 '%S', # 挿入/削除される文字列 '%v', # validateオプションで指定した種類 '%V', # 実際に実施されたvalidateの種類 '%W' # Entryウィジェットの名前 )) self.entry.pack() # 入力値の正否判定関数 def hizuke_onValidate(self, d, i, p, s, S, v, V, W): print("onValidat in") # 入力キー不正のフラッグ(NG時はng=1) ng = 0 # 異常の有った時点で処理するため「break」でループを抜ける for i in range(1): # (1)エントリーの初期表示を「"yy/mm/dd"」と設定 if V == 'focusin': print("forcus in 1") # 最初にフォーカスインした時「"yy/mm/dd"」を表示させる処理 var = self.entry.get() if len(str.split(var)) == 0: ng = 1 break # (2)半角数字以外の時は不可 if V == 'key': # 挿入文字位置i表示 print("挿入文字列「ラージS=」" + S + " 挿入前文字列「スモールs」=" + s + " 文字位置「i」=" + str(i)) if S == "yy/mm/dd": break # 英数半角以外NG if unicodedata.east_asian_width(S) != 'Na': ng = 1 # 数字以外の時は不可 if S.isdecimal() == False: ng = 1 # 半角数字以外時に挿入前表示に戻す if ng == 1: # forループを抜ける break print("onValidate out") # カーソルを指定位置に移動 if ng == 1: return False else: return True # 入力値不適の後処理関数 def hizuke_inValidate(self, d, i, p, s, S, v, V, W): print("inValidate in ") for i in range(1): if V == 'focusin': print("forcus in 2") var = self.entry.get() if len(str.split(var)) == 0: self.entry.insert(0, "yy/mm/dd") break print("inValidate out") if __name__ == "__main__": root = tk.Tk() app = Application(master = root) app.mainloop()

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問