@@ -41,32 +41,22 @@ def translate_key(key, modifiers):
4141 return f'Key-{ key } '
4242
4343
44- class GetKeysDialog ( Toplevel ):
44+ class GetKeysFrame ( Frame ):
4545
4646 # Dialog title for invalid key sequence
4747 keyerror_title = 'Key Sequence Error'
4848
49- def __init__ (self , parent , title , action , current_key_sequences ,
50- * , _htest = False , _utest = False ):
49+ def __init__ (self , parent , action , current_key_sequences ):
5150 """
5251 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
5553 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
5755 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
6056 """
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'
7060 self .parent = parent
7161 self .action = action
7262 self .current_key_sequences = current_key_sequences
@@ -82,39 +72,14 @@ def __init__(self, parent, title, action, current_key_sequences,
8272 self .modifier_vars .append (variable )
8373 self .advanced = False
8474 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 ()
9775
9876 def showerror (self , * args , ** kwargs ):
9977 # Make testing easier. Replace in #30751.
10078 messagebox .showerror (* args , ** kwargs )
10179
10280 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-
11681 # Basic entry key sequence.
117- self .frame_keyseq_basic = Frame (frame , name = 'keyseq_basic' )
82+ self .frame_keyseq_basic = Frame (self , name = 'keyseq_basic' )
11883 self .frame_keyseq_basic .grid (row = 0 , column = 0 , sticky = 'nsew' ,
11984 padx = 5 , pady = 5 )
12085 basic_title = Label (self .frame_keyseq_basic ,
@@ -127,7 +92,7 @@ def create_widgets(self):
12792 basic_keys .pack (ipadx = 5 , ipady = 5 , fill = 'x' )
12893
12994 # Basic entry controls.
130- self .frame_controls_basic = Frame (frame )
95+ self .frame_controls_basic = Frame (self )
13196 self .frame_controls_basic .grid (row = 1 , column = 0 , sticky = 'nsew' , padx = 5 )
13297
13398 # Basic entry modifiers.
@@ -169,7 +134,7 @@ def create_widgets(self):
169134 self .button_clear .grid (row = 2 , column = 0 , columnspan = 4 )
170135
171136 # Advanced entry key sequence.
172- self .frame_keyseq_advanced = Frame (frame , name = 'keyseq_advanced' )
137+ self .frame_keyseq_advanced = Frame (self , name = 'keyseq_advanced' )
173138 self .frame_keyseq_advanced .grid (row = 0 , column = 0 , sticky = 'nsew' ,
174139 padx = 5 , pady = 5 )
175140 advanced_title = Label (self .frame_keyseq_advanced , justify = 'left' ,
@@ -181,7 +146,7 @@ def create_widgets(self):
181146 self .advanced_keys .pack (fill = 'x' )
182147
183148 # Advanced entry help text.
184- self .frame_help_advanced = Frame (frame )
149+ self .frame_help_advanced = Frame (self )
185150 self .frame_help_advanced .grid (row = 1 , column = 0 , sticky = 'nsew' , padx = 5 )
186151 help_advanced = Label (self .frame_help_advanced , justify = 'left' ,
187152 text = "Key bindings are specified using Tkinter keysyms as\n " +
@@ -196,7 +161,7 @@ def create_widgets(self):
196161 help_advanced .grid (row = 0 , column = 0 , sticky = 'nsew' )
197162
198163 # 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 ,
200165 text = '<< Basic Key Binding Entry' )
201166 self .button_level .grid (row = 2 , column = 0 , stick = 'ew' , padx = 5 , pady = 5 )
202167 self .toggle_level ()
@@ -257,21 +222,16 @@ def clear_key_seq(self):
257222 variable .set ('' )
258223 self .key_string .set ('' )
259224
260- def ok (self , event = None ):
225+ def ok (self ):
226+ self .result = ''
261227 keys = self .key_string .get ().strip ()
262228 if not keys :
263229 self .showerror (title = self .keyerror_title , parent = self ,
264230 message = "No key specified." )
265231 return
266232 if (self .advanced or self .keys_ok (keys )) and self .bind_ok (keys ):
267233 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
275235
276236 def keys_ok (self , keys ):
277237 """Validity check on user's 'basic' keybinding selection.
@@ -319,6 +279,73 @@ def bind_ok(self, keys):
319279 return True
320280
321281
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+
322349if __name__ == '__main__' :
323350 from unittest import main
324351 main ('idlelib.idle_test.test_config_key' , verbosity = 2 , exit = False )
0 commit comments