前提・実現したいこと
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/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
あなたの回答
tips
プレビュー