Finding the widget name which generated an event

Jeff Epler jepler at unpythonic.net
Tue May 6 10:34:15 EDT 2003


I don't see why you don't use two functions.  If some part of the work
is common (which it isn't in your above example) then just call the
common function.

If you really insist on using this approach, you can use 'is' to check
whether it's one widget or the other:
    def validity_check(event):
        common stuff
        if event.widget is First:
             do string validation for 1st entrywidget
        else if entry.widget is Second:
             do integer validation for 2nd entrywidget
        other common stuff

but you'll quickly find that this becomes unmanagable as you add widgets.

The alternative is
    def string_validity_check(event):
        common_stuff()
        do string validation for event.widget
        other_common_stuff()

    def int_validity_check likewise

    e.bind("<FocusOut>", string_validity_check)
    f.bind("<FocusOut>", int_validity_check)

You could also use subclassing to validate different types of widgets.

    class ValidatedEntry(Tkinter.Entry):
        def __init__(self, *args, **kw):
            Tkinter.Entry.__init__(*args, **kw)
            self.bind("<FocusOut>", self.validity_check)

        def common_stuff(self): pass
        def other_common_stuff(self): pass

    class StringEntry(ValidatedEntry):
        def validity_check(self, event):
            self.common_stuff()
            do string validation for self / event.widget (they are the same)
            self.other_common_stuff()

Using FocusOut to perform validation has one other drawback that I
should mention: you'll see a <FocusOut> event not only when the user
presses Tab or clicks on another field, but also if she switches to a
different application (which may be done before the input is "complete",
for instance if she wants to refer to a value in a different window in
choosing the value to enter here).  In one software package I worked on
it was decided that when the user left a field and it didn't validate,
a dialog would be shown telling her the valid range of values.  This led
to piles of problems, because showing the dialog would cause another
<FocusOut> event!  To make this work properly, we ended up replacing
almost all of the focus- and traversal-related machinery that Tk provides,
and there are still probably bugs---it's certainly less maintainable.
Even just writing
    if not contents_valid(event.widget):
        # move focus back to a widget when its contents are invalid
        event.widget.focus()
can lead to grief: imagine the other widget selected was *also* invalid.
Now you'll have a tug-of-war for keyboard focus from which the program
will likely never recover.

That leaves only passive actions for invalid entry contents.
For instance, you could choose to color the background read (instead
of white or grey) when the contents of a field are not valid.  But I
don't know of any user interface guide that recommends this practice.
For starters, you don't know in advance what the user's color scheme is,
and I don't think any major UI standard defines an "alert" background
color---so, by coloring the background red you might decrease or destroy
the visual contrast between the foreground and background of the widget.

I consulted 2 of the 3 user interface guides I usually refer to and I
didn't immediately find a section discussing ways to inform the user
that entered information is incorrect (Galitz' "It's Time to Clean Your
Windows" and Johnson's "GUI Bloopers" -- I also usually refer to the
Microsoft Windows User Experience book, but it's out of my office right
now) so either I looked past it in the index or this isn't a problem
with an accepted solution.

(and let me say that, even as a Unix bigot, that MWUE seems to contain
a fair amount of good advice on creating a consistent user interface,
though it's interspersed with "rules for anal-retentive win32 application
creators" such as the minimum and maximum dialog size in "DLUs".  I
can't recommend enough that, if you're going to design user interfaces,
you educate yourself about what good user interface is)

Jeff Epler
jepler at unpythonic.net





More information about the Python-list mailing list