前提・実現したいこと
すみません、インデントが全く出ていませんでした。修正しました、よろしくお願いします。
tkinterのENTRYウェジェットのvalidatecommand、invalidcommandで日付入力の検証をしました。これをウェジェットの表示部分と検証部分に分割するとエラーが発生します(ワンファイル時は正常に動作)。この対処法を指摘ください。
ついでで恐縮ですがtkinterのmessageboxのフォントサイズ指定法を教えて下さい。
ここに質問の内容を詳しく書いてください。
(例)PHP(CakePHP)で●●なシステムを作っています。
■■な機能を実装中に以下のエラーメッセージが発生しました。
発生している問題・エラーメッセージ
Traceback (most recent call last): File "C:\Users\akiteru\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__ return self.func(*args) TypeError: hizuke_onValidate() missing 1 required positional argument: 'W'エラーメッセージ
該当のソースコード
# ****** t1.py ***** import tkinter as tk import tkinter.ttk as ttk # 全半角判定用 import unicodedata # キーイベント入手 from msvcrt import getch # メッセージボックス from tkinter import messagebox import t2 class MainWindow(ttk.Frame): def __init__(self, parent): super(MainWindow, self).__init__(parent) self.parent = parent # 第1のエントリーオブジェクト self.frame2 = tk.Frame(pady=5) self.frame2.pack(fill="x") self.label2 = tk.Label(self.frame2,font=("",14),text="区 分 ") self.label2.pack(side="left") self.entry2 = tk.Entry(self.frame2,font=("",14),justify="left", width=12) self.entry2.pack(side="left") # **********日付入力領域 self.frame1 = tk.Frame(pady=5) self.frame1.pack(fill="x") self.label1 = tk.Label(self.frame1,font=("",14),text="日 付 ") self.label1.pack(side="left") self.entry1 = tk.Entry(self.frame1,font=("",14),justify="left", width=12) self.entry1.insert("end", "yy/mm/dd") # ***** エントリー1への入力を判定(validatecommandの設定) vcm_onValidate = (self.register(t2.hizuke_onValidate), '%d', '%i', '%p', '%s', '%S', '%v', '%V', '%W') vcm_inValidate = (self.register(t2.hizuke_inValidate), '%d', '%i', '%p', '%s', '%S', '%v', '%V', '%W') self.entry1["validate"] = "all" self.entry1["validatecommand"] = vcm_onValidate self.entry1["invalidcommand"] = vcm_inValidate self.entry1.pack(side="left") # 第3のエントリーオブジェクト self.frame3 = tk.Frame(pady=5) self.frame3.pack(fill="x") self.label3 = tk.Label(self.frame3,font=("",14),text="名 前 ") self.label3.pack(side="left") self.entry3 = tk.Entry(self.frame3,font=("",14),justify="left", width=12) self.entry3.pack(side="left") application = tk.Tk() application.geometry("800x500") application.title('PyPost') window = MainWindow(application) application.protocol('WM_DELETE_WINDOW', window.quit) application.mainloop() # ****** t2.py ****** import tkinter as tk import tkinter.ttk as ttk # 全半角判定用 import unicodedata # キーイベント入手 from msvcrt import getch # メッセージボックス from tkinter import messagebox # ***** 日付入力の検証関数(validatecommandとinvalidcommandを組み合わせて処理) def hizuke_onValidate(self, d, i, p, s, S, v, V, W): # validateで入力値、カーソル位置を変更することができない # この為、検証を含め全ての処理をhizuke_inValidate(invalidcommand)で処理 # ⇒戻り値Falseのみセットする return False def hizuke_inValidate(self, d, i, p, s, S, v, V, W): # (1)フォーカスイン/アウトの処理(アウトで入力値検証) if d == '-1': # フォーカスイン時の処理(初期設定値「yy/mm/dd」の時カーソルを先頭設定) if V == 'focusin': dummy = self.entry1.get() if dummy == 'yy/mm/dd': # 初期設定値の時 self.entry1.icursor('0') # フォーカスアウト時は日付入値の検証実行 if V == 'focusout': # 数字部分文字列抽出 dummy = self.entry1.get() # 年月日に分割 yy = dummy[0:2] mm = dummy[3:5] dd = dummy[6:8] ymd = yy + mm + dd # 日付入力のエラー有無Flg(エラー有=1 無=0) flg = 0 # エラー訂正意思有の場合のカーソルを戻す位置 pos = '0' # エラー時のメッセージ文 msg = '' # (1)年月日が数字で無い時はNG if ymd.isdecimal() == False: flg = 1 pos = '0' msg = '日付入力が不適です' else: # 年月日数値検証(年は00~99迄入力可の為、検証せず) # (2)月検証(01~12) if int(mm) > 12 or int(mm) < 1: flg = 1 pos = '3' msg = '月の入力が不適です' else: # (3)指定月の日検証(01~31) # 各月の最大数列 d = (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30,31) m = int(mm) -1 if int(dd) > d[m]: flg = 1 pos= '6' msg = '日の入力が不適です' # エラーの時訂正意思確認 # 訂正意思の戻り値 if flg == 1: res = '' res = messagebox.askquestion("注 意", msg + '訂正しますか?') if res == 'yes': # 訂正する場合 self.entry1.icursor(pos) self.entry1.focus_set() else: # 訂正し無い時(初期設定の「yy/mm/dd」表示に戻す) self.entry1.delete(0, 'end') self.entry1.insert(0,'yy/mm/dd') # (2)削除処理の時。削除位置の表示を「/、y、m、d」に変更 if d == '0': # 表示文字列作成(消去文字位置により戻す文字を変える) ymd = ('y' ,'y', '/', 'm', 'm', '/', 'd', 'd', '') new_var = s[0:int(i)] + ymd[int(i)] + s[int(i)+1:] self.entry1.delete(0, 'end') self.entry1.insert(0, new_var) self.entry1.icursor(i) # (3)挿入処理の時 if d == '1': # 入力文字が半角数字以外NG。8文字目以上入力不可(⇒入力前の文字列に戻す) flg = 0 # 9文字目(i=8)からは入力禁止 if int(i) > 7: flg = 1 # 英数半角以外NG。数字以外NG if unicodedata.east_asian_width(S) != 'Na' or S.isdecimal() == False: flg = 1 # 入力位置及び入力文字種異常の時は表示を元に戻す if flg == 1: self.entry1.delete(0, 'end') self.entry1.insert(0, s) self.entry1.icursor(i) # 入力文字種が正常の時の処理(主に「/」を挟んでのカーソル移動制御) if flg == 0: # 今回の入力位置 ichi = int(i) # 年月日入力が入力された時の表示文字列(「/」位置で入力があった場合は例外処理) new_var = s[0:ichi] + S + s[ichi + 1:] # 入力後のカーソル設定位置(通常現在位置の次。「/」位置の場合「/」の後に移動の為+2⇒別処理) pos = int(i) + 1 # 年、月の第2文字目入力の時 if i == '1' or i == '4': # 次の「/」の後ろにカーソル移動pos = pos + 1 pos = pos + 1 # 年、月の後の「/」に入力された時 # 入力値を消去しカーソル位置を「/」の後に強制移動 if i == '2' or i == '5' : new_var = s # 判定後の文字列表示 self.entry1.delete(0, 'end') self.entry1.insert(0, new_var) self.entry1.icursor(str(pos)) # 以下を入れないとフォーカスイン時は%d=-1だが文字入力すると%d=0の削除となる vcm_onValidate = (self.register(t2.hizuke_onValidate), '%d', '%i', '%p', '%s', '%S', '%v', '%V', '%W') vcm_inValidate = (self.register(t2.hizuke_inValidate), '%d', '%i', '%p', '%s', '%S', '%v', '%V', '%W') self.entry1["validate"] = "all" self.entry1["validatecommand"] = vcm_onValidate self.entry1["invalidcommand"] = vcm_inValidate ソースコード
試したこと
ワンファイルの時は下記にあるt1.py、t2.pyにある[t2.]は[self.]としてありました。
***** エントリー1への入力を判定(validatecommandの設定)
vcm_onValidate = (self.register(t2.hizuke_onValidate), '%d', '%i', '%p', '%s', '%S', '%v', '%V', '%W') vcm_inValidate = (self.register(t2.hizuke_inValidate), '%d', '%i', '%p', '%s', '%S', '%v', '%V', '%W')
ここに問題に対して試したことを記載してください。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー