update idletasks

update idletasks

This subcommand of update flushes all currently-scheduled idle events from Tcl's event queue.

Idle events are used to postpone processing until “there is nothing else to do”, with the typical use case for them being Tk's redrawing and geometry recalculations. By postponing these until Tk is idle, expensive redraw operations are not done until everything from a cluster of events (e.g., button release, change of current window, etc.) are processed at the script level. This makes Tk seem much faster, but if you're in the middle of doing some long running processing, it can also mean that no idle events are processed for a long time. By calling update idletasks, redraws due to internal changes of state are processed immediately. (Redraws due to system events, e.g., being deiconified by the user, need a full update to be processed.)

APN As described in Update considered harmful, use of update to handle redraws not handled by update idletasks has many issues. Joe English in a comp.lang.tcl posting describes an alternative:


(From Joe from clt )

As noted, most Tk widgets redraw themselves at idle-time, so update idletasks will perform any pending redisplays.

They generally *schedule* redisplays in response to <Expose> and <Configure> events, and these come in through the main event loop. So if you update idletasks immediately after packing a window, it won't necessarily redraw itself because it might not know that it needs to be redrawn yet!

You can see this in action if you add the following to the original test script:

    bind all <Map> { puts "MAP: %W" }
    bind all <Expose> { puts "EXPOSE: %W" }

You can force a redisplay without reentering the main event loop by sending a synthetic <Expose> event:

    pack $w ...
    event generate $w <Expose> -when now
    update idletasks

('-when now' is the default for event generate, so strictly speaking it's unnecessary, but I like to write it out explicitly in cases where it makes a difference, as it does here.)

MHo 2012-03-13 I have a situation here where the trick shown above does not force redraw. Up until now the only way is a full update...