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