<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:times new roman,new york,times,serif;font-size:12pt">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.<br><br>I'll paste the working code below. It's partially in Dutch, but hey, so is Guido van Rossem. ;-)<br><br>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.<br><br>from Tkinter import *<br><br>def createWidgets(veldnamen):<br> root=Tk()<br> termenlijst = {"Naam": set(["Bill Gates", "Elvis Presley"]),<br> "*Postcode":
set(["2600AA", "8000BB"]),<br> "Adres": set(["Street", "Avenue"])}<br> handleDeletions = {}<br> for veldnaam in veldnamen:<br> labelWidget=Label(root, text=veldnaam, takefocus=False)<br> labelWidget.grid()<br> # tcl names must start with a lowercase letter<br> tclName = veldnaam[0].lower() + veldnaam[1:]<br> content = StringVar()<br> entryWidget=Entry(root, name=tclName, textvariable=content)<br> entryWidget.grid()<br><br> def handleDeletion(event, widget=entryWidget, root=root,
termenlijst=termenlijst,content=content):<br> actieveVenster = root.focus_get()<br> actieveVensternaam = str(actieveVenster)[1:].capitalize()<br> if actieveVensternaam.startswith("*"):<br> actieveVensternaam = "*" + actieveVensternaam[1:].capitalize()<br> vensterinhoud = content.get().strip()<br> print "Name: %s -- Contents: %s" % (actieveVensternaam, vensterinhoud)<br> try:<br>
termenlijst[actieveVensternaam].remove(vensterinhoud)<br> actieveVenster.delete(0, END)<br> print "Deleted term '%s'" % vensterinhoud<br> except KeyError:<br> print "No such term '%s'" % vensterinhoud<br> pass<br> handleDeletions[entryWidget] = handleDeletion<br><br> for entryWidget, handleDeletion in handleDeletions.iteritems():<br> entryWidget.bind("<Shift-Delete>", handleDeletion)<br><br>createWidgets(["Naam", "*Postcode",
"Adres"])<br><br><br> <br><div> </div>Cheers!!<br>Albert-Jan<br><br><div>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>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?<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<div><br></div><div style="font-family: times new roman,new york,times,serif; font-size: 12pt;"><br><div style="font-family: times new roman,new york,times,serif; font-size: 12pt;"><font face="Tahoma" size="2"><hr size="1"><b><span style="font-weight: bold;">From:</span></b> Albert-Jan Roskam <fomcl@yahoo.com><br><b><span style="font-weight: bold;">To:</span></b> Python Mailing List <tutor@python.org><br><b><span style="font-weight: bold;">Sent:</span></b> Fri, December 3, 2010 11:19:02 AM<br><b><span style="font-weight:
bold;">Subject:</span></b> [Tutor] Question on tkinter event binding<br></font><br>
<div style="font-family: times new roman,new york,times,serif; font-size: 12pt;">Hi,<br><br>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. <br><br>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.<br><br>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.<br><br><span><span>[1] <a target="_blank" href="http://tkinter.unpythonic.net/wiki/AutocompleteEntry">http://tkinter.unpythonic.net/wiki/AutocompleteEntry</a></span></span><br><span><span>[2] <a target="_blank" href="http://www.daniweb.com/code/snippet306072.html">http://www.daniweb.com/code/snippet306072.html</a></span></span><br><br>from Tkinter import *<br><br>def createWidgets(veldnamen):<br> root=Tk()<br> termenlijst = {"Naam": set(["Bill Gates", "Elvis Presley"]), "*Postcode": set(["2600AA", "8000NN"])}<br> handleDels =
{}<br> for veldnaam
in veldnamen:<br> # tcl names must start with lowercase letter<br> entryWidget=Entry(root, name=veldnaam[0].lower() + veldnaam[1:])<br> entryWidget.grid()<br> def handleDel(event, widget=entryWidget, root=root, termenlijst=termenlijst):<br> vensternaam = str(root.focus_get())[1:].capitalize() # ... and back to uppercase<br> if vensternaam.startswith("*"): # mandatory fields start with '*' in my program.<br> vensternaam = "*" + vensternaam[1:].capitalize()<br> vensterinhoud =
entryWidget.get()<br> print "Naam", vensternaam # entry name<br> print "Inhoud", vensterinhoud # entry contents<br> try:<br> termenlijst[vensternaam].remove(vensterinhoud) # here's where the typo is removed<br> except KeyError:<br> pass # user tries to delete a term that doesn't exist in the termenlijst.<br> handleDels[entryWidget] = handleDel<br> # do all the bindings (is this where it goes
wrong??)<br> for entryWidget, handleDel in handleDels.iteritems():<br> entryWidget.bind("<Delete>", handleDel)<br> print handleDels<br> print termenlijst<br><br>createWidgets(["Naam", "*Postcode"])<br><div> <br>Thanks again for having a look at this.<br><br></div>Cheers!!<br>Albert-Jan<br><br><div>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>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?<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<div><br></div></div>
</div><br>
</div></div></div>
</div><br>
</body></html>