Aaahhh, got it! Peace! I did two things wrong: (1) I didn't use a tcl StringVar() to get the entry widget contents (2) I didn't consistently close the menus generated by previous attempts to run the program, which led to inconsistent results.
I'll paste the working code below. It's partially in Dutch, but hey, so is Guido van Rossem. ;-) Even so, I'd be happy to hear suggestions for improvement or simplification. I'd love to chop the code up into smaller, more comprehensible bits. from Tkinter import * def createWidgets(veldnamen): root=Tk() termenlijst = {"Naam": set(["Bill Gates", "Elvis Presley"]), "*Postcode": set(["2600AA", "8000BB"]), "Adres": set(["Street", "Avenue"])} handleDeletions = {} for veldnaam in veldnamen: labelWidget=Label(root, text=veldnaam, takefocus=False) labelWidget.grid() # tcl names must start with a lowercase letter tclName = veldnaam[0].lower() + veldnaam[1:] content = StringVar() entryWidget=Entry(root, name=tclName, textvariable=content) entryWidget.grid() def handleDeletion(event, widget=entryWidget, root=root, termenlijst=termenlijst,content=content): actieveVenster = root.focus_get() actieveVensternaam = str(actieveVenster)[1:].capitalize() if actieveVensternaam.startswith("*"): actieveVensternaam = "*" + actieveVensternaam[1:].capitalize() vensterinhoud = content.get().strip() print "Name: %s -- Contents: %s" % (actieveVensternaam, vensterinhoud) try: termenlijst[actieveVensternaam].remove(vensterinhoud) actieveVenster.delete(0, END) print "Deleted term '%s'" % vensterinhoud except KeyError: print "No such term '%s'" % vensterinhoud pass handleDeletions[entryWidget] = handleDeletion for entryWidget, handleDeletion in handleDeletions.iteritems(): entryWidget.bind("<Shift-Delete>", handleDeletion) createWidgets(["Naam", "*Postcode", "Adres"]) Cheers!! Albert-Jan ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a fresh water system, and public health, what have the Romans ever done for us? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ________________________________ From: Albert-Jan Roskam <fo...@yahoo.com> To: Python Mailing List <tutor@python.org> Sent: Fri, December 3, 2010 11:19:02 AM Subject: [Tutor] Question on tkinter event binding Hi, I'm trying to make a small improvement on a data entry program and it is literally giving me a headache. I would appreciate your help or suggestions. The actual program uses Autocomplete entry widgets [1], which is a subclass of the Tkinter Entry widget. The sample code below uses a simple Entry widget, for the sake of simplicity. The autocompletions are recorded in a dictionary of the form {entry name: set(<entries>)}. The problem is that entries with typos cannot be deleted, so wrong autocomplete suggestions ("Bbbilly Gates") are given until the end of time. My solution: I want to bind each entry widget to the Delete key, which makes it possible to remove the typo-entry from the set of entries. I am using an ' expanded event handler' [2] to do the event binding. The sample code below creates two entry widgets. The problem is that the entry contents is not retrieved correctly. If I fill the 2nd entry with some text, then hit 'Del' , it shows the content of the *first* entry. Also, I would like to isolate the event handler into its own function, not as a function within a function, but I'm not quite sure how. [1] http://tkinter.unpythonic.net/wiki/AutocompleteEntry [2] http://www.daniweb.com/code/snippet306072.html from Tkinter import * def createWidgets(veldnamen): root=Tk() termenlijst = {"Naam": set(["Bill Gates", "Elvis Presley"]), "*Postcode": set(["2600AA", "8000NN"])} handleDels = {} for veldnaam in veldnamen: # tcl names must start with lowercase letter entryWidget=Entry(root, name=veldnaam[0].lower() + veldnaam[1:]) entryWidget.grid() def handleDel(event, widget=entryWidget, root=root, termenlijst=termenlijst): vensternaam = str(root.focus_get())[1:].capitalize() # ... and back to uppercase if vensternaam.startswith("*"): # mandatory fields start with '*' in my program. vensternaam = "*" + vensternaam[1:].capitalize() vensterinhoud = entryWidget.get() print "Naam", vensternaam # entry name print "Inhoud", vensterinhoud # entry contents try: termenlijst[vensternaam].remove(vensterinhoud) # here's where the typo is removed except KeyError: pass # user tries to delete a term that doesn't exist in the termenlijst. handleDels[entryWidget] = handleDel # do all the bindings (is this where it goes wrong??) for entryWidget, handleDel in handleDels.iteritems(): entryWidget.bind("<Delete>", handleDel) print handleDels print termenlijst createWidgets(["Naam", "*Postcode"]) Thanks again for having a look at this. Cheers!! Albert-Jan ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a fresh water system, and public health, what have the Romans ever done for us? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
_______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor