[Tutor] tkinter binding issues

Wayne Werner waynejwerner at gmail.com
Wed Oct 19 21:37:40 CEST 2011


On Wed, Oct 19, 2011 at 9:05 AM, Elwin Estle <elwin.estle at gmail.com> wrote:

> <snip> So, here is the first 'bug'.  In all three of the callback
> functions, I added an extra dummy parameter because I kept getting an error
> message about the callback wanting two parameters, even though I do not pass
> any parameters and don't really need to.  The dummy parameter does nothing
> and isn't referenced in the function code.  But without it, why do I get the
> error message?
>

Tkinter passes the event to your callback, so you can get information such
as the keypress and mouse location.

If you don't need the event, you can simply wrap the function call in a
lambda function,, sort of the inverse of what you do when you want to pass a
parameter on a button click:

bind("<FocusOut>", lambda x: callback())


> The second bug has to do with the routine starting on line 385, which
> resets all the widgets in the input form to their starting values.  If just
> click inside the three entry widgets, without inputting any data, the
> backgrounds turn red, as they should.  However, when I click the clear form
> button, which calls the function on line 385, it doesn't always reset these
> entry boxes back to their original state.  It only will do so if the cursor
> is in the "clock number" entry box.  If it is in one of the other two boxes,
> it will clear all the boxes but that one.


> If I comment out the first line of the reset form function (the one that
> sets focus back to the clock number entry widget, then all three are
> cleared, but the cursor isn't where I want it to be.  I get the idea that
> when focus shifts from whatever box the cursor is in, to the 'yes' button in
> the tkmessagebox, that it triggers my validation callback and turns the
> background red, but shouldn't my clear form function still clear it out?
>

That's because of the way the events are handled in Tkinter. I believe it's
because when you call self.reset_form(), it actually fires that before the
<FocusOut> event fires, so it goes through that whole reset process, returns
focus to your other box and *then* the <FocusOut> event. I'd have to throw
some print's in to make sure, but I suspect that's the issue. I was able to
get around it by simply changing the call to :

    self.after(10, self.reset_form)
    self.focus_set()

I tried using update_idletasks, but I couldn't get any combination of that
working. I suspect that this method works because the after command tells it
to wait for at least 10ms, and in that time the <FocusOut> event can be
called.

Alternatively, you could remove focus from the Entry widget before you call
the messagebox. If you wanted to get fancy, you could use <FocusIn> to keep
track of which widget has the focus and return to that widget if the user
clicks "No" on the confirmation dialog.

HTH,
Wayne
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20111019/7f01b894/attachment-0001.html>


More information about the Tutor mailing list