[Tutor] Question on tkinter event binding

Albert-Jan Roskam fomcl at yahoo.com
Fri Dec 3 11:19:02 CET 2010


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?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



      
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20101203/ec868262/attachment.html>


More information about the Tutor mailing list