@@ -41,32 +41,22 @@ def translate_key(key, modifiers):
41
41
return f'Key-{ key } '
42
42
43
43
44
- class GetKeysDialog ( Toplevel ):
44
+ class GetKeysFrame ( Frame ):
45
45
46
46
# Dialog title for invalid key sequence
47
47
keyerror_title = 'Key Sequence Error'
48
48
49
- def __init__ (self , parent , title , action , current_key_sequences ,
50
- * , _htest = False , _utest = False ):
49
+ def __init__ (self , parent , action , current_key_sequences ):
51
50
"""
52
51
parent - parent of this dialog
53
- title - string which is the title of the popup dialog
54
- action - string, the name of the virtual event these keys will be
52
+ action - the name of the virtual event these keys will be
55
53
mapped to
56
- current_key_sequences - list, a list of all key sequence lists
54
+ current_key_sequences - a list of all key sequence lists
57
55
currently mapped to virtual events, for overlap checking
58
- _htest - bool, change box location when running htest
59
- _utest - bool, do not wait when running unittest
60
56
"""
61
- Toplevel .__init__ (self , parent )
62
- self .withdraw () # Hide while setting geometry.
63
- self .configure (borderwidth = 5 )
64
- self .resizable (height = False , width = False )
65
- self .title (title )
66
- self .transient (parent )
67
- _setup_dialog (self )
68
- self .grab_set ()
69
- self .protocol ("WM_DELETE_WINDOW" , self .cancel )
57
+ super ().__init__ (parent )
58
+ self ['borderwidth' ] = 2
59
+ self ['relief' ] = 'sunken'
70
60
self .parent = parent
71
61
self .action = action
72
62
self .current_key_sequences = current_key_sequences
@@ -82,39 +72,14 @@ def __init__(self, parent, title, action, current_key_sequences,
82
72
self .modifier_vars .append (variable )
83
73
self .advanced = False
84
74
self .create_widgets ()
85
- self .update_idletasks ()
86
- self .geometry (
87
- "+%d+%d" % (
88
- parent .winfo_rootx () +
89
- (parent .winfo_width ()/ 2 - self .winfo_reqwidth ()/ 2 ),
90
- parent .winfo_rooty () +
91
- ((parent .winfo_height ()/ 2 - self .winfo_reqheight ()/ 2 )
92
- if not _htest else 150 )
93
- ) ) # Center dialog over parent (or below htest box).
94
- if not _utest :
95
- self .deiconify () # Geometry set, unhide.
96
- self .wait_window ()
97
75
98
76
def showerror (self , * args , ** kwargs ):
99
77
# Make testing easier. Replace in #30751.
100
78
messagebox .showerror (* args , ** kwargs )
101
79
102
80
def create_widgets (self ):
103
- self .frame = frame = Frame (self , borderwidth = 2 , relief = 'sunken' )
104
- frame .pack (side = 'top' , expand = True , fill = 'both' )
105
-
106
- frame_buttons = Frame (self )
107
- frame_buttons .pack (side = 'bottom' , fill = 'x' )
108
-
109
- self .button_ok = Button (frame_buttons , text = 'OK' ,
110
- width = 8 , command = self .ok )
111
- self .button_ok .grid (row = 0 , column = 0 , padx = 5 , pady = 5 )
112
- self .button_cancel = Button (frame_buttons , text = 'Cancel' ,
113
- width = 8 , command = self .cancel )
114
- self .button_cancel .grid (row = 0 , column = 1 , padx = 5 , pady = 5 )
115
-
116
81
# Basic entry key sequence.
117
- self .frame_keyseq_basic = Frame (frame , name = 'keyseq_basic' )
82
+ self .frame_keyseq_basic = Frame (self , name = 'keyseq_basic' )
118
83
self .frame_keyseq_basic .grid (row = 0 , column = 0 , sticky = 'nsew' ,
119
84
padx = 5 , pady = 5 )
120
85
basic_title = Label (self .frame_keyseq_basic ,
@@ -127,7 +92,7 @@ def create_widgets(self):
127
92
basic_keys .pack (ipadx = 5 , ipady = 5 , fill = 'x' )
128
93
129
94
# Basic entry controls.
130
- self .frame_controls_basic = Frame (frame )
95
+ self .frame_controls_basic = Frame (self )
131
96
self .frame_controls_basic .grid (row = 1 , column = 0 , sticky = 'nsew' , padx = 5 )
132
97
133
98
# Basic entry modifiers.
@@ -169,7 +134,7 @@ def create_widgets(self):
169
134
self .button_clear .grid (row = 2 , column = 0 , columnspan = 4 )
170
135
171
136
# Advanced entry key sequence.
172
- self .frame_keyseq_advanced = Frame (frame , name = 'keyseq_advanced' )
137
+ self .frame_keyseq_advanced = Frame (self , name = 'keyseq_advanced' )
173
138
self .frame_keyseq_advanced .grid (row = 0 , column = 0 , sticky = 'nsew' ,
174
139
padx = 5 , pady = 5 )
175
140
advanced_title = Label (self .frame_keyseq_advanced , justify = 'left' ,
@@ -181,7 +146,7 @@ def create_widgets(self):
181
146
self .advanced_keys .pack (fill = 'x' )
182
147
183
148
# Advanced entry help text.
184
- self .frame_help_advanced = Frame (frame )
149
+ self .frame_help_advanced = Frame (self )
185
150
self .frame_help_advanced .grid (row = 1 , column = 0 , sticky = 'nsew' , padx = 5 )
186
151
help_advanced = Label (self .frame_help_advanced , justify = 'left' ,
187
152
text = "Key bindings are specified using Tkinter keysyms as\n " +
@@ -196,7 +161,7 @@ def create_widgets(self):
196
161
help_advanced .grid (row = 0 , column = 0 , sticky = 'nsew' )
197
162
198
163
# Switch between basic and advanced.
199
- self .button_level = Button (frame , command = self .toggle_level ,
164
+ self .button_level = Button (self , command = self .toggle_level ,
200
165
text = '<< Basic Key Binding Entry' )
201
166
self .button_level .grid (row = 2 , column = 0 , stick = 'ew' , padx = 5 , pady = 5 )
202
167
self .toggle_level ()
@@ -257,21 +222,16 @@ def clear_key_seq(self):
257
222
variable .set ('' )
258
223
self .key_string .set ('' )
259
224
260
- def ok (self , event = None ):
225
+ def ok (self ):
226
+ self .result = ''
261
227
keys = self .key_string .get ().strip ()
262
228
if not keys :
263
229
self .showerror (title = self .keyerror_title , parent = self ,
264
230
message = "No key specified." )
265
231
return
266
232
if (self .advanced or self .keys_ok (keys )) and self .bind_ok (keys ):
267
233
self .result = keys
268
- self .grab_release ()
269
- self .destroy ()
270
-
271
- def cancel (self , event = None ):
272
- self .result = ''
273
- self .grab_release ()
274
- self .destroy ()
234
+ return
275
235
276
236
def keys_ok (self , keys ):
277
237
"""Validity check on user's 'basic' keybinding selection.
@@ -319,6 +279,73 @@ def bind_ok(self, keys):
319
279
return True
320
280
321
281
282
+ class GetKeysWindow (Toplevel ):
283
+
284
+ def __init__ (self , parent , title , action , current_key_sequences ,
285
+ * , _htest = False , _utest = False ):
286
+ """
287
+ parent - parent of this dialog
288
+ title - string which is the title of the popup dialog
289
+ action - string, the name of the virtual event these keys will be
290
+ mapped to
291
+ current_key_sequences - list, a list of all key sequence lists
292
+ currently mapped to virtual events, for overlap checking
293
+ _htest - bool, change box location when running htest
294
+ _utest - bool, do not wait when running unittest
295
+ """
296
+ super ().__init__ (parent )
297
+ self .withdraw () # Hide while setting geometry.
298
+ self ['borderwidth' ] = 5
299
+ self .resizable (height = False , width = False )
300
+ # Needed for winfo_reqwidth().
301
+ self .update_idletasks ()
302
+ # Center dialog over parent (or below htest box).
303
+ x = (parent .winfo_rootx () +
304
+ (parent .winfo_width ()// 2 - self .winfo_reqwidth ()// 2 ))
305
+ y = (parent .winfo_rooty () +
306
+ ((parent .winfo_height ()// 2 - self .winfo_reqheight ()// 2 )
307
+ if not _htest else 150 ))
308
+ self .geometry (f"+{ x } +{ y } " )
309
+
310
+ self .title (title )
311
+ self .frame = frame = GetKeysFrame (self , action , current_key_sequences )
312
+ self .protocol ("WM_DELETE_WINDOW" , self .cancel )
313
+ frame_buttons = Frame (self )
314
+ self .button_ok = Button (frame_buttons , text = 'OK' ,
315
+ width = 8 , command = self .ok )
316
+ self .button_cancel = Button (frame_buttons , text = 'Cancel' ,
317
+ width = 8 , command = self .cancel )
318
+ self .button_ok .grid (row = 0 , column = 0 , padx = 5 , pady = 5 )
319
+ self .button_cancel .grid (row = 0 , column = 1 , padx = 5 , pady = 5 )
320
+ frame .pack (side = 'top' , expand = True , fill = 'both' )
321
+ frame_buttons .pack (side = 'bottom' , fill = 'x' )
322
+
323
+ self .transient (parent )
324
+ _setup_dialog (self )
325
+ self .grab_set ()
326
+ if not _utest :
327
+ self .deiconify () # Geometry set, unhide.
328
+ self .wait_window ()
329
+
330
+ @property
331
+ def result (self ):
332
+ return self .frame .result
333
+
334
+ @result .setter
335
+ def result (self , value ):
336
+ self .frame .result = value
337
+
338
+ def ok (self , event = None ):
339
+ self .frame .ok ()
340
+ self .grab_release ()
341
+ self .destroy ()
342
+
343
+ def cancel (self , event = None ):
344
+ self .result = ''
345
+ self .grab_release ()
346
+ self .destroy ()
347
+
348
+
322
349
if __name__ == '__main__' :
323
350
from unittest import main
324
351
main ('idlelib.idle_test.test_config_key' , verbosity = 2 , exit = False )
0 commit comments