11"""
2- dialog for building tkinter accelerator key bindings
2+ Dialog for building Tkinter accelerator key bindings
33"""
44from Tkinter import *
55import tkMessageBox
@@ -49,9 +49,9 @@ def CreateWidgets(self):
4949 frameMain .pack (side = TOP ,expand = TRUE ,fill = BOTH )
5050 frameButtons = Frame (self )
5151 frameButtons .pack (side = BOTTOM ,fill = X )
52- self .buttonOk = Button (frameButtons ,text = 'Ok ' ,
53- width = 8 ,command = self .Ok )
54- self .buttonOk .grid (row = 0 ,column = 0 ,padx = 5 ,pady = 5 )
52+ self .buttonOK = Button (frameButtons ,text = 'OK ' ,
53+ width = 8 ,command = self .OK )
54+ self .buttonOK .grid (row = 0 ,column = 0 ,padx = 5 ,pady = 5 )
5555 self .buttonCancel = Button (frameButtons ,text = 'Cancel' ,
5656 width = 8 ,command = self .Cancel )
5757 self .buttonCancel .grid (row = 0 ,column = 1 ,padx = 5 ,pady = 5 )
@@ -85,9 +85,13 @@ def CreateWidgets(self):
8585 self .modifier_checkbuttons [modifier ] = check
8686 column += 1
8787 labelFnAdvice = Label (self .frameControlsBasic ,justify = LEFT ,
88- text = "Select the desired modifier\n " +
89- "keys above, and final key\n " +
90- "from the list on the right." )
88+ text = \
89+ "Select the desired modifier keys\n " +
90+ "above, and the final key from the\n " +
91+ "list on the right.\n \n " +
92+ "Use upper case Symbols when using\n " +
93+ "the Shift modifier. (Letters will be\n " +
94+ "converted automatically.)" )
9195 labelFnAdvice .grid (row = 1 ,column = 0 ,columnspan = 4 ,padx = 2 ,sticky = W )
9296 self .listKeysFinal = Listbox (self .frameControlsBasic ,width = 15 ,height = 10 ,
9397 selectmode = SINGLE )
@@ -102,17 +106,19 @@ def CreateWidgets(self):
102106 self .buttonClear .grid (row = 2 ,column = 0 ,columnspan = 4 )
103107 labelTitleAdvanced = Label (self .frameKeySeqAdvanced ,justify = LEFT ,
104108 text = "Enter new binding(s) for '" + self .action + "' :\n " +
105- "(will not be checked for validity)" )
109+ "(These bindings will not be checked for validity! )" )
106110 labelTitleAdvanced .pack (anchor = W )
107111 self .entryKeysAdvanced = Entry (self .frameKeySeqAdvanced ,
108112 textvariable = self .keyString )
109113 self .entryKeysAdvanced .pack (fill = X )
110114 labelHelpAdvanced = Label (self .frameHelpAdvanced ,justify = LEFT ,
111- text = "Key bindings are specified using tkinter key id's as\n " +
115+ text = "Key bindings are specified using Tkinter keysyms as\n " +
112116 "in these samples: <Control-f>, <Shift-F2>, <F12>,\n "
113- "<Control-space>, <Meta-less>, <Control-Alt-Shift-x>.\n \n " +
114- "'Emacs style' multi-keystroke bindings are specified as\n " +
115- "follows: <Control-x><Control-y> or <Meta-f><Meta-g>.\n \n " +
117+ "<Control-space>, <Meta-less>, <Control-Alt-Shift-X>.\n "
118+ "Upper case is used when the Shift modifier is present!\n \n " +
119+ "'Emacs style' multi-keystroke bindings are specified as\n " +
120+ "follows: <Control-x><Control-y>, where the first key\n " +
121+ "is the 'do-nothing' keybinding.\n \n " +
116122 "Multiple separate bindings for one action should be\n " +
117123 "separated by a space, eg., <Alt-v> <Meta-v>." )
118124 labelHelpAdvanced .grid (row = 0 ,column = 0 ,sticky = NSEW )
@@ -149,20 +155,12 @@ def FinalKeySelected(self,event):
149155 self .BuildKeyString ()
150156
151157 def BuildKeyString (self ):
152- keyList = []
153- modifiers = self .GetModifiers ()
154- finalKey = self .listKeysFinal .get (ANCHOR )
155- if modifiers : modifiers [0 ]= '<' + modifiers [0 ]
156- keyList = keyList + modifiers
158+ keyList = modifiers = self .GetModifiers ()
159+ finalKey = self .listKeysFinal .get (ANCHOR )
157160 if finalKey :
158- if (not modifiers ) and (finalKey not
159- in self .alphanumKeys + self .punctuationKeys ):
160- finalKey = '<' + self .TranslateKey (finalKey )
161- else :
162- finalKey = self .TranslateKey (finalKey )
163- keyList .append (finalKey + '>' )
164- keyStr = string .join (keyList ,'-' )
165- self .keyString .set (keyStr )
161+ finalKey = self .TranslateKey (finalKey , modifiers )
162+ keyList .append (finalKey )
163+ self .keyString .set ('<' + string .join (keyList ,'-' ) + '>' )
166164
167165 def GetModifiers (self ):
168166 modList = [variable .get () for variable in self .modifier_vars ]
@@ -190,65 +188,67 @@ def LoadFinalKeyList(self):
190188 self .whitespaceKeys + self .editKeys + self .moveKeys )
191189 self .listKeysFinal .insert (END , * keys )
192190
193- def TranslateKey (self ,key ):
194- #translate from key list value to tkinter key-id
195- translateDict = {'~' :'asciitilde' ,'!' :'exclam' ,'@' :'at' ,'#' :'numbersign' ,
191+ def TranslateKey (self , key , modifiers ):
192+ "Translate from keycap symbol to the Tkinter keysym"
193+ translateDict = {'Space' :'space' ,
194+ '~' :'asciitilde' ,'!' :'exclam' ,'@' :'at' ,'#' :'numbersign' ,
196195 '%' :'percent' ,'^' :'asciicircum' ,'&' :'ampersand' ,'*' :'asterisk' ,
197196 '(' :'parenleft' ,')' :'parenright' ,'_' :'underscore' ,'-' :'minus' ,
198197 '+' :'plus' ,'=' :'equal' ,'{' :'braceleft' ,'}' :'braceright' ,
199198 '[' :'bracketleft' ,']' :'bracketright' ,'|' :'bar' ,';' :'semicolon' ,
200199 ':' :'colon' ,',' :'comma' ,'.' :'period' ,'<' :'less' ,'>' :'greater' ,
201200 '/' :'slash' ,'?' :'question' ,'Page Up' :'Prior' ,'Page Down' :'Next' ,
202201 'Left Arrow' :'Left' ,'Right Arrow' :'Right' ,'Up Arrow' :'Up' ,
203- 'Down Arrow' : 'Down' }
202+ 'Down Arrow' : 'Down' , 'Tab' : 'tab' }
204203 if key in translateDict .keys ():
205- key = translateDict [key ]
206- key = 'Key-' + key
204+ key = translateDict [key ]
205+ if 'Shift' in modifiers and key in string .ascii_lowercase :
206+ key = key .upper ()
207+ key = 'Key-' + key
207208 return key
208209
209- def Ok (self , event = None ):
210- if self .KeysOk ():
210+ def OK (self , event = None ):
211+ if self .KeysOK ():
211212 self .result = self .keyString .get ()
212213 self .destroy ()
213214
214215 def Cancel (self , event = None ):
215216 self .result = ''
216217 self .destroy ()
217218
218- def KeysOk (self ):
219- #simple validity check
220- keysOk = 1
221- keys = self .keyString .get ()
219+ def KeysOK (self ):
220+ "Validity check on user's keybinding selection"
221+ keys = self .keyString .get ()
222222 keys .strip ()
223- finalKey = self .listKeysFinal .get (ANCHOR )
224- modifiers = self .GetModifiers ()
225- keySequence = keys . split () #make into a key sequence list for overlap check
226- if not keys : #no keys specified
227- tkMessageBox . showerror ( title = 'Key Sequence Error' ,
228- message = 'No keys specified.' )
229- keysOk = 0
230- elif not keys . endswith ( '>' ): #no final key specified
231- tkMessageBox . showerror ( title = 'Key Sequence Error' ,
232- message = 'No final key specified.' )
233- keysOk = 0
234- elif ( not modifiers ) and ( finalKey in
235- self .alphanumKeys + self . punctuationKeys ) :
236- #modifier required
237- tkMessageBox . showerror ( title = 'Key Sequence Error' ,
238- message = 'No modifier key(s) specified.' )
239- keysOk = 0
240- elif ( modifiers == [ 'Shift' ]) and ( finalKey not
241- in self . functionKeys + ( 'Tab' ,)):
242- #shift alone is only a useful modifier with a function key
243- tkMessageBox .showerror (title = 'Key Sequence Error' ,
244- message = 'Shift alone is not a useful modifier ' +
245- 'when used with this final key key.' )
246- keysOk = 0
247- elif keySequence in self . currentKeySequences : #keys combo already in use
248- tkMessageBox . showerror ( title = 'Key Sequence Error' ,
249- message = 'This key combination is already in use.' )
250- keysOk = 0
251- return keysOk
223+ finalKey = self .listKeysFinal .get (ANCHOR )
224+ modifiers = self .GetModifiers ()
225+ # create a key sequence list for overlap check:
226+ keySequence = keys . split ()
227+ keysOK = False
228+ title = 'Key Sequence Error'
229+ if not keys :
230+ tkMessageBox . showerror ( title = title , parent = self ,
231+ message = 'No keys specified.' )
232+ elif not keys . endswith ( '>' ):
233+ tkMessageBox . showerror ( title = title , parent = self ,
234+ message = 'Missing the final Key' )
235+ elif not modifiers and finalKey not in self .functionKeys :
236+ tkMessageBox . showerror ( title = title , parent = self ,
237+ message = 'No modifier key(s) specified.' )
238+ elif ( modifiers == [ 'Shift' ]) \
239+ and ( finalKey not in
240+ self . functionKeys + ( 'Tab' , 'Space' )):
241+ msg = 'The shift modifier by itself may not be used with' \
242+ ' this key symbol; only with F1-F12, Tab, or Space'
243+ tkMessageBox .showerror (title = title , parent = self ,
244+ message = msg )
245+ elif keySequence in self . currentKeySequences :
246+ msg = 'This key combination is already in use.'
247+ tkMessageBox . showerror ( title = title , parent = self ,
248+ message = msg )
249+ else :
250+ keysOK = True
251+ return keysOK
252252
253253if __name__ == '__main__' :
254254 #test the dialog
0 commit comments