質問編集履歴

1

インデントが全く出ていませんでした。修正しました。

2020/05/11 07:19

投稿

akiteru
akiteru

スコア21

test CHANGED
File without changes
test CHANGED
@@ -1,8 +1,18 @@
1
1
  ### 前提・実現したいこと
2
2
 
3
- pythontkinterのentryウィジェットのvalidatecommand、invalidcommandを使test.pyは常に動作します。これをウィジェットを配置動作させるメイン部分のt1.pyとdef hizuke_onValidate(self, d, i, p, s, S, v, V, W)とdef hizuke_inValidate(self, d, i, p, s, S, v, V, W)を記しt2.pyの2つのファイルに分割t1.pyを実行すると下記エラーとなります。
4
-
5
- ついで質問で恐縮ですがmessageboxフォントが小さく、この設定方法をご教授ください。
3
+ すみません、インデントが全く出ていません。修正しました、よろくお願いします。
4
+
5
+ tkinterENTRYウェジェットのvalidatecommand、invalidcommandで日付入力検証をしました。これをウェジェッの表示部分と検証部分に分割するとエラー発生します(ワンファイル時は正常に動作)。この対処法を指摘ください。
6
+
7
+ ついでで恐縮ですがtkinterのmessageboxのフォントサイズ指定法を教えて下さい。
8
+
9
+
10
+
11
+ ここに質問の内容を詳しく書いてください。
12
+
13
+ (例)PHP(CakePHP)で●●なシステムを作っています。
14
+
15
+ ■■な機能を実装中に以下のエラーメッセージが発生しました。
6
16
 
7
17
 
8
18
 
@@ -10,23 +20,29 @@
10
20
 
11
21
 
12
22
 
23
+ ```
24
+
13
25
  Traceback (most recent call last):
14
26
 
15
27
  File "C:\Users\akiteru\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
16
28
 
17
29
  return self.func(*args)
18
30
 
19
- TypeError: hizuke_onValidate() missing 1 required positional argument: 'W'```、
31
+ TypeError: hizuke_onValidate() missing 1 required positional argument: 'W'エラーメッセージ
32
+
20
-
33
+ ```
21
-
22
34
 
23
35
 
24
36
 
25
37
  ### 該当のソースコード
26
38
 
39
+
40
+
27
- (1)********* 正常動作するtest.py ************
41
+ ```ここ言語名を入力
28
-
42
+
43
+
44
+
29
- # *** test.py ****
45
+ # ****** t1.py *****
30
46
 
31
47
  import tkinter as tk
32
48
 
@@ -44,6 +60,8 @@
44
60
 
45
61
  from tkinter import messagebox
46
62
 
63
+ import t2
64
+
47
65
 
48
66
 
49
67
  class MainWindow(ttk.Frame):
@@ -84,31 +102,31 @@
84
102
 
85
103
 
86
104
 
87
- self.entry4_1 = tk.Entry(self.frame1,font=("",14),justify="left", width=12)
105
+ self.entry1 = tk.Entry(self.frame1,font=("",14),justify="left", width=12)
88
-
106
+
89
- self.entry4_1.insert("end", "yy/mm/dd")
107
+ self.entry1.insert("end", "yy/mm/dd")
90
108
 
91
109
 
92
110
 
93
111
  # ***** エントリー1への入力を判定(validatecommandの設定)
94
112
 
95
- vcm_onValidate = (self.register(self.hizuke_onValidate),
113
+ vcm_onValidate = (self.register(t2.hizuke_onValidate),
96
114
 
97
115
  '%d', '%i', '%p', '%s', '%S', '%v', '%V', '%W')
98
116
 
99
- vcm_inValidate = (self.register(self.hizuke_inValidate),
117
+ vcm_inValidate = (self.register(t2.hizuke_inValidate),
100
118
 
101
119
  '%d', '%i', '%p', '%s', '%S', '%v', '%V', '%W')
102
120
 
103
- self.entry4_1["validate"] = "all"
121
+ self.entry1["validate"] = "all"
104
-
122
+
105
- self.entry4_1["validatecommand"] = vcm_onValidate
123
+ self.entry1["validatecommand"] = vcm_onValidate
106
-
124
+
107
- self.entry4_1["invalidcommand"] = vcm_inValidate
125
+ self.entry1["invalidcommand"] = vcm_inValidate
108
-
109
-
110
-
126
+
127
+
128
+
111
- self.entry4_1.pack(side="left")
129
+ self.entry1.pack(side="left")
112
130
 
113
131
 
114
132
 
@@ -126,310 +144,334 @@
126
144
 
127
145
  self.entry3.pack(side="left")
128
146
 
147
+
148
+
129
-
149
+ application = tk.Tk()
150
+
151
+ application.geometry("800x500")
152
+
153
+ application.title('PyPost')
154
+
155
+ window = MainWindow(application)
156
+
157
+ application.protocol('WM_DELETE_WINDOW', window.quit)
158
+
159
+ application.mainloop()
160
+
161
+
162
+
163
+ # ****** t2.py ******
164
+
165
+
166
+
167
+ import tkinter as tk
168
+
169
+ import tkinter.ttk as ttk
170
+
171
+ # 全半角判定用
172
+
173
+ import unicodedata
174
+
175
+ # キーイベント入手
176
+
177
+ from msvcrt import getch
178
+
179
+ # メッセージボックス
180
+
181
+ from tkinter import messagebox
182
+
183
+
184
+
185
+ # ***** 日付入力の検証関数(validatecommandとinvalidcommandを組み合わせて処理)
186
+
187
+ def hizuke_onValidate(self, d, i, p, s, S, v, V, W):
188
+
189
+ # validateで入力値、カーソル位置を変更することができない
190
+
191
+ # この為、検証を含め全ての処理をhizuke_inValidate(invalidcommand)で処理
192
+
193
+ # ⇒戻り値Falseのみセットする
194
+
195
+ return False
130
196
 
131
197
 
132
198
 
133
-
134
-
135
- # ***** 日付入力検証関数(validatecommandとinvalidcommandを組み合わせて処理
136
-
137
- def hizuke_onValidate(self, d, i, p, s, S, v, V, W):
138
-
139
- # validateで入力値、カーソル位置変更することができない
140
-
141
- # この為、検証を含め全ての処理をhizuke_inValidate(invalidcommand)で処理
142
-
143
- # ⇒戻り値Falseのみセットする
144
-
145
- return False
146
-
147
-
148
-
149
- def hizuke_inValidate(self, d, i, p, s, S, v, V, W):
150
-
151
- # (1)フォーカスイン/アウトの処理(アウトで入力値検証)
152
-
153
- if d == '-1':
154
-
155
- # フォーカスイン時の処理(初期設定値「yy/mm/dd」の時カーソルを先頭設定)
156
-
157
- if V == 'focusin':
158
-
159
- dummy = self.entry4_1.get()
160
-
161
- if dummy == 'yy/mm/dd':
162
-
163
- # 初期設定値の時
164
-
165
- self.entry4_1.icursor('0')
166
-
167
-
168
-
169
- # フォーカスアウト時は日付入値の検証実行
170
-
171
- if V == 'focusout':
172
-
173
- # 数字部分文字列抽出
174
-
175
- dummy = self.entry4_1.get()
176
-
177
- # 年月日に分割
178
-
179
- yy = dummy[0:2]
180
-
181
- mm = dummy[3:5]
182
-
183
- dd = dummy[6:8]
184
-
185
- ymd = yy + mm + dd
186
-
187
- # 日付入力のエラー有無Flg(エラー有=1 無=0)
188
-
189
- flg = 0
190
-
191
- # エラー訂正意思有の場合のカーソルを戻す位置
199
+ def hizuke_inValidate(self, d, i, p, s, S, v, V, W):
200
+
201
+ # (1)フォーカスイン/アウトの処理(アウトで入力検証)
202
+
203
+ if d == '-1':
204
+
205
+ # フォーカスイン時の処理(初期設定値「yy/mm/dd」の時カーソルを先頭設定)
206
+
207
+ if V == 'focusin':
208
+
209
+ dummy = self.entry1.get()
210
+
211
+ if dummy == 'yy/mm/dd':
212
+
213
+ # 初期設定値の時
214
+
215
+ self.entry1.icursor('0')
216
+
217
+
218
+
219
+ # フォーカスアウト時は日付入値の検証実行
220
+
221
+ if V == 'focusout':
222
+
223
+ # 数字部分文字列抽出
224
+
225
+ dummy = self.entry1.get()
226
+
227
+ # 年月日に分割
228
+
229
+ yy = dummy[0:2]
230
+
231
+ mm = dummy[3:5]
232
+
233
+ dd = dummy[6:8]
234
+
235
+ ymd = yy + mm + dd
236
+
237
+ # 日付入力のエラー有無Flg(エラー有=1 無=0)
238
+
239
+ flg = 0
240
+
241
+ # エラー訂正意思有の場合のカーソルを戻す位置
242
+
243
+ pos = '0'
244
+
245
+ # エラー時のメッセージ文
246
+
247
+ msg = ''
248
+
249
+
250
+
251
+ # (1)年月日が数字で無い時はNG
252
+
253
+ if ymd.isdecimal() == False:
254
+
255
+ flg = 1
192
256
 
193
257
  pos = '0'
194
258
 
259
+ msg = '日付入力が不適です'
260
+
261
+ else:
262
+
263
+ # 年月日数値検証(年は00~99迄入力可の為、検証せず)
264
+
265
+ # (2)月検証(01~12)
266
+
267
+ if int(mm) > 12 or int(mm) < 1:
268
+
269
+ flg = 1
270
+
271
+ pos = '3'
272
+
273
+ msg = '月の入力が不適です'
274
+
275
+ else:
276
+
277
+ # (3)指定月の日検証(01~31)
278
+
279
+ # 各月の最大数列
280
+
281
+ d = (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30,31)
282
+
283
+ m = int(mm) -1
284
+
285
+ if int(dd) > d[m]:
286
+
287
+ flg = 1
288
+
289
+ pos= '6'
290
+
291
+ msg = '日の入力が不適です'
292
+
293
+
294
+
195
- # エラー時のメッセージ文
295
+ # エラー訂正意思確認
296
+
196
-
297
+ # 訂正意思の戻り値
298
+
299
+ if flg == 1:
300
+
197
- msg = ''
301
+ res = ''
302
+
303
+ res = messagebox.askquestion("注 意", msg + '訂正しますか?')
304
+
305
+ if res == 'yes':
306
+
307
+ # 訂正する場合
308
+
309
+ self.entry1.icursor(pos)
310
+
311
+ self.entry1.focus_set()
312
+
313
+ else:
314
+
315
+ # 訂正し無い時(初期設定の「yy/mm/dd」表示に戻す)
316
+
317
+ self.entry1.delete(0, 'end')
318
+
319
+ self.entry1.insert(0,'yy/mm/dd')
320
+
321
+
322
+
323
+ # (2)削除処理の時。削除位置の表示を「/、y、m、d」に変更
324
+
325
+ if d == '0':
326
+
327
+ # 表示文字列作成(消去文字位置により戻す文字を変える)
328
+
329
+ ymd = ('y' ,'y', '/', 'm', 'm', '/', 'd', 'd', '')
330
+
331
+ new_var = s[0:int(i)] + ymd[int(i)] + s[int(i)+1:]
332
+
333
+
334
+
335
+ self.entry1.delete(0, 'end')
336
+
337
+ self.entry1.insert(0, new_var)
338
+
339
+ self.entry1.icursor(i)
340
+
341
+
342
+
343
+ # (3)挿入処理の時
344
+
345
+ if d == '1':
346
+
347
+ # 入力文字が半角数字以外NG。8文字目以上入力不可(⇒入力前の文字列に戻す)
348
+
349
+ flg = 0
350
+
351
+ # 9文字目(i=8)からは入力禁止
352
+
353
+ if int(i) > 7:
354
+
355
+ flg = 1
356
+
357
+
358
+
359
+ # 英数半角以外NG。数字以外NG
360
+
361
+ if unicodedata.east_asian_width(S) != 'Na' or S.isdecimal() == False:
362
+
363
+ flg = 1
364
+
365
+
366
+
367
+ # 入力位置及び入力文字種異常の時は表示を元に戻す
368
+
369
+ if flg == 1:
370
+
371
+ self.entry1.delete(0, 'end')
372
+
373
+ self.entry1.insert(0, s)
374
+
375
+ self.entry1.icursor(i)
376
+
377
+
378
+
379
+ # 入力文字種が正常の時の処理(主に「/」を挟んでのカーソル移動制御)
380
+
381
+ if flg == 0:
382
+
383
+ # 今回の入力位置
384
+
385
+ ichi = int(i)
386
+
387
+ # 年月日入力が入力された時の表示文字列(「/」位置で入力があった場合は例外処理)
388
+
389
+ new_var = s[0:ichi] + S + s[ichi + 1:]
390
+
391
+ # 入力後のカーソル設定位置(通常現在位置の次。「/」位置の場合「/」の後に移動の為+2⇒別処理)
392
+
393
+ pos = int(i) + 1
198
394
 
199
395
 
200
396
 
201
- # (1)年月日が数字で無い時はNG
202
-
203
- if ymd.isdecimal() == False:
204
-
205
- flg = 1
206
-
207
- pos = '0'
208
-
209
- msg = '日付入力が不適です'
210
-
211
- else:
212
-
213
- # 年月日数値検証(年は00~99迄入力可の為、検証せず)
214
-
215
- # (2)月検証(01~12)
216
-
217
- if int(mm) > 12 or int(mm) < 1:
218
-
219
- flg = 1
220
-
221
- pos = '3'
222
-
223
- msg = '月の入力が不適です'
224
-
225
- else:
226
-
227
- # (3)指定月の日検証(01~31)
228
-
229
- # 各月の最大数列
230
-
231
- d = (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30,31)
232
-
233
- m = int(mm) -1
234
-
235
- if int(dd) > d[m]:
236
-
237
- flg = 1
238
-
239
- pos= '6'
240
-
241
- msg = '日の入力が不適です'
242
-
243
-
244
-
245
- # エラーの時訂正意思確認
246
-
247
- # 訂正意思の戻り値
248
-
249
- if flg == 1:
250
-
251
- res = ''
252
-
253
- res = messagebox.askquestion("注 意", msg + '訂正しますか?')
254
-
255
- if res == 'yes':
256
-
257
- # 訂正する場合
258
-
259
- self.entry4_1.icursor(pos)
260
-
261
- self.entry4_1.focus_set()
262
-
263
- else:
264
-
265
- # 訂正し無い時(初期設定の「yy/mm/dd」表示に戻す)
266
-
267
- self.entry4_1.delete(0, 'end')
268
-
269
- self.entry4_1.insert(0,'yy/mm/dd')
270
-
271
-
272
-
273
- # (2)削除処理の時。削除位置の表示を「/、y、m、d」に変更
274
-
275
- if d == '0':
276
-
277
- # 表示文字列作成(消去文字位置により戻す文字を変える)
278
-
279
- ymd = ('y' ,'y', '/', 'm', 'm', '/', 'd', 'd', '')
280
-
281
- new_var = s[0:int(i)] + ymd[int(i)] + s[int(i)+1:]
282
-
283
-
284
-
285
- self.entry4_1.delete(0, 'end')
286
-
287
- self.entry4_1.insert(0, new_var)
288
-
289
- self.entry4_1.icursor(i)
290
-
291
-
292
-
293
- # (3)挿処理の時
397
+ # 年、月の第2文字目の時
294
-
398
+
295
- if d == '1':
399
+ if i == '1' or i == '4':
296
-
400
+
297
- # 入力文字が半角数字以外NG。8文字目以上入力不可(⇒入力前文字列戻す)
401
+ # 「/」の後ろカーソル移動pos = pos + 1
298
-
299
- flg = 0
402
+
300
-
301
- # 9文字目(i=8)からは入力禁止
302
-
303
- if int(i) > 7:
304
-
305
- flg = 1
403
+ pos = pos + 1
306
404
 
307
405
 
308
406
 
309
- # 英数半角以外NG。数字以外NG
310
-
311
- if unicodedata.east_asian_width(S) != 'Na' or S.isdecimal() == False:
312
-
313
- flg = 1
314
-
315
-
316
-
317
- # 入力位置及び入力文字種異常の時は表示を元に戻す
318
-
319
- if flg == 1:
320
-
321
- self.entry4_1.delete(0, 'end')
322
-
323
- self.entry4_1.insert(0, s)
324
-
325
- self.entry4_1.icursor(i)
326
-
327
-
328
-
329
- # 入文字種が正常時の処理(主に「/」を挟んでのカーソル移動制御)
330
-
331
- if flg == 0:
332
-
333
- # 今回の入力位置
334
-
335
- ichi = int(i)
336
-
337
- # 年月日入力が入力された時の表示文字列(「/」位置で入力があった場合は例外処理)
338
-
339
- new_var = s[0:ichi] + S + s[ichi + 1:]
340
-
341
- # 入力後のカーソル設定位置(通常現在位置の次。「/」位置の場合「/」の後に移動の為+2⇒別処理)
342
-
343
- pos = int(i) + 1
344
-
345
-
346
-
347
- # 年、月の第2文字目入力の時
348
-
349
- if i == '1' or i == '4':
350
-
351
- # 次の「/」の後ろにカーソル移動pos = pos + 1
352
-
353
- pos = pos + 1
354
-
355
-
356
-
357
- # 年、月後の「/」入力され
358
-
359
- # 入力消去しカーソル位置を「/」後に強制移動
360
-
361
- if i == '2' or i == '5' :
362
-
363
- new_var = s
364
-
365
-
366
-
367
- # 判定後の文字列表示
368
-
369
- self.entry4_1.delete(0, 'end')
370
-
371
- self.entry4_1.insert(0, new_var)
372
-
373
- self.entry4_1.icursor(str(pos))
374
-
375
-
376
-
377
- # 以下を入れないとフォーカスイン時は%d=-1だが文字入力すると%d=0の削除となる
378
-
379
- vcm_onValidate = (self.register(self.hizuke_onValidate),
407
+ # 年、月の後の「/」に入力された時
408
+
409
+ # 入力値を消去しカーソル位置を「/」の後に強制移動
410
+
411
+ if i == '2' or i == '5' :
412
+
413
+ new_var = s
414
+
415
+
416
+
417
+ # 判定後の文字列表示
418
+
419
+ self.entry1.delete(0, 'end')
420
+
421
+ self.entry1.insert(0, new_var)
422
+
423
+ self.entry1.icursor(str(pos))
424
+
425
+
426
+
427
+ # 以下をれないとフォーカスイン時は%d=-1だが文字入力すると%d=0削除となる
428
+
429
+ vcm_onValidate = (self.register(t2.hizuke_onValidate),
430
+
431
+ '%d', '%i', '%p', '%s', '%S', '%v', '%V', '%W')
432
+
433
+ vcm_inValidate = (self.register(t2.hizuke_inValidate),
434
+
435
+ '%d', '%i', '%p', '%s', '%S', '%v', '%V', '%W')
436
+
437
+ self.entry1["validate"] = "all"
438
+
439
+ self.entry1["validatecommand"] = vcm_onValidate
440
+
441
+ self.entry1["invalidcommand"] = vcm_inValidate
442
+
443
+
444
+
445
+
446
+
447
+ ソースコード
448
+
449
+ ```
450
+
451
+
452
+
453
+ ### 試したこと
454
+
455
+ ワンファイル時は下記あるt1.py、t2.pyにある[t2.]は[self.]としてありまし
456
+
457
+ # ***** エントリー1への入力を判定(validatecommand設定)
458
+
459
+ vcm_onValidate = (self.register(t2.hizuke_onValidate),
380
460
 
381
461
  '%d', '%i', '%p', '%s', '%S', '%v', '%V', '%W')
382
462
 
383
- vcm_inValidate = (self.register(self.hizuke_inValidate),
463
+ vcm_inValidate = (self.register(t2.hizuke_inValidate),
384
464
 
385
465
  '%d', '%i', '%p', '%s', '%S', '%v', '%V', '%W')
386
466
 
387
- self.entry4_1["validate"] = "all"
467
+
388
-
389
- self.entry4_1["validatecommand"] = vcm_onValidate
468
+
390
-
391
- self.entry4_1["invalidcommand"] = vcm_inValidate
392
-
393
-
394
-
395
-
396
-
397
- application = tk.Tk()
398
-
399
- application.geometry("800x500")
400
-
401
- application.title('PyPost')
402
-
403
- window = MainWindow(application)
404
-
405
- application.protocol('WM_DELETE_WINDOW', window.quit)
406
-
407
- application.mainloop()
469
+ ここに問題に対して試したことを記載してください。
408
-
409
-
410
470
 
411
471
 
412
472
 
413
473
  ### 補足情報(FW/ツールのバージョンなど)
414
474
 
475
+
476
+
415
- コード分割際し下の変更をしています
477
+ ここより詳細な情報をしてください。
416
-
417
- vcm_onValidate = (self.register(self.hizuke_onValidate)の第2の「self」は「t2」変更し
418
-
419
- vcm_onValidate = (self.register(t2.hizuke_onValidate)としています。
420
-
421
- vcm_inValidate = (self.register(self.hizuke_inValidate)の第2の「self」についても同様の処理をしています。
422
-
423
- ```
424
-
425
- ```
426
-
427
- ### 補足情報(FW/ツールのバージョンなど)
428
-
429
- コード分割に際しての変更点は以下の点のみです。
430
-
431
- vcm_onValidate = (self.register(self.hizuke_onValidate)の第2の「self」は「t2」変更し
432
-
433
- vcm_onValidate = (self.register(t2.hizuke_onValidate)としています。
434
-
435
- vcm_inValidate = (self.register(self.hizuke_inValidate)の第2の「self」についても同様の処理をしています。