[Tkinter-discuss] busy cursor stores up events

Jeff Epler jepler at unpythonic.net
Wed Apr 20 04:16:32 CEST 2005


Those examples don't seem to do anything besides change the cursor
displayed when the mouse is over the affected widgets.  They don't do
any true "busy" handling.

Apparently PMW provides an interface to the Blt "busy" command, which
does a little better.  With "busy", I think you set an entire toplevel
(or maybe just a widget tree) busy, and any mouse actions taken in the
meantime have no effect.

I think the two gotchas are in BLT's implementation of busy are that
* Keyboard input is not handled by busy, only mouse input
* An "update" is needed so that the widget created by Blt to consume 
  mouse events actually gets to consume them.  If the busy ends before
  events are handled, they end up being handled by the real widget
  clicked instead.

I've used BLT's "busy" only once, and at the Tk level, not with the
interface PWM provides.  Here's the code I came up with, with most of the
app-specific bits removed and a few comments added.  Overall, I felt
like it was very fiddly and I'm still not sure it's right.

def open_file_guts(f):
    old_focus = root_window.tk.call("focus", "-lastfor", ".")
    root_window.tk.call("blt::busy", "hold", ".")
    # blt::busy adds a fake window that keeps mouse events from reaching
    # widgets.  It does nothing about keys.  To hide key events, I must
    # first provide a widget that will be given keyboard focus.  It must
    # break on <Key> events, because most keybindings are on . which
    # means they are automatically applied to all widgets in the
    # top-level window.  In order to focus the window, it must be
    # visible.  I place it in a location that should be offscreen.
    root_window.tk.call("label", "._busy")
    root_window.tk.call("bind", "._busy", "<Key>", "break")
    root_window.tk.call("place", "._busy", "-x", "9999", "-y", "9999")
    root_window.tk.call("focus", "-force", "._busy")
    root_window.update()

    try:
        # app-specific stuff here which might take awhile.
        # It is best if the code in here calls "update" from time to
        # time
    finally:
        # Before unbusying, I update again, so that any keystroke events
        # that reached the program while it was busy are sent to the
        # label, not to another window in the application.  If this
        # update call is removed, the events are only handled after that
        # widget is destroyed and focus has passed to some other widget,
        # which will handle the keystrokes instead, leading to the
        # R-while-loading bug.
        root_window.update()
        root_window.tk.call("blt::busy", "release", ".")
        root_window.tk.call("destroy", "._busy")
        root_window.tk.call("focus", old_focus)


Jeff
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://mail.python.org/pipermail/tkinter-discuss/attachments/20050419/0c008070/attachment.pgp


More information about the Tkinter-discuss mailing list