Synopsis edit
- update ?idletasks?
See Also edit
Description edit
update services all outstanding events, including those that come due while update is operating. It was provided to allow tasks such as refreshing a GUI to happen immediately. coroutine provides another way to structure code so that events can be serviced at strategic points in the control flow. Even before coroutine was available, many Tcl programmers found that if the need to use update arises, it's a clue that the script should be restructured. See notes by kbk, below.update works by performing the following steps in a loop until no events are serviced in one iteration:- Service the first event whose scheduled time has come.
- If no such events are found, service all events currently in the idle queue, but not those added once this step starts.
KBK 2000-02-12: My personal opinion is that update is not one of the best practices, and a programmer is well advised to avoid it. I have seldom if ever seen a use of update that could not be more effectively programmed by another means, generally appropriate use of event callbacks. By the way, this caution applies to all the Tcl commands (vwait and tkwait are the other common culprits) that enter the event loop recursively, with the exception of using a single vwait at global level to launch the event loop inside a shell that doesn't launch it automatically.The commonest purposes for which I've seen update recommended are:
- Keeping the GUI alive while some long-running calculation is executing. See Countdown program for an alternative.
- Waiting for a window to be configured before doing things like geometry management on it. The alternative is to bind on events such as <Configure> that notify the process of a window's geometry. See Centering a window for an alternative.
Processing Selected Events edit
TFW 2003-08-11: Occasionally we need to allow certain events to be processed while withholding others. To allow this I took the existing update implementation and modified it to allow allowable event types. For example, calling "updateEventObjCmd timers" allows timers that are scheduled to fire, but withholds gui updates. This can be very useful to work around some of the problems mentioned here./* ---------------------------------------------------------------------- updateEventObjCmd -- Granular version of the Update command, can be used to only allow certain events to occur. e.g. updateEvents timers will allow background timers to fire without allow window updates to occur. updateEvents windows will only allow other events to occur if a window event was also processed. Results: A standard Tcl result. Side effects: See the user documentation. ---------------------------------------------------------------------- */ static int updateEventObjCmd ( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ) { int optionIndex; int flags = 0; static char *updateOptions[] = {"windows","files","timers","idle", "all", (char *) NULL}; enum updateOptions { WIN_EVENTS, FILE_EVENTS, TIMER_EVENTS, IDLE_EVENTS,ALL_EVENTS }; if (objc == 1) { flags = TCL_ALL_EVENTS|TCL_DONT_WAIT; } else if (objc == 2) { if (Tcl_GetIndexFromObj(interp, objv[1], updateOptions,"option", 0, &optionIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum updateOptions) optionIndex) { case WIN_EVENTS: { flags = TCL_WINDOW_EVENTS|TCL_DONT_WAIT; break; } case FILE_EVENTS: { flags = TCL_FILE_EVENTS|TCL_DONT_WAIT; break; } case TIMER_EVENTS: { flags = TCL_TIMER_EVENTS|TCL_DONT_WAIT; break; } case IDLE_EVENTS: { flags = TCL_IDLE_EVENTS|TCL_DONT_WAIT; break; } case ALL_EVENTS: { flags = TCL_ALL_EVENTS|TCL_DONT_WAIT; break; } default: { panic("Tcl_UpdateObjCmd: bad option index to updateEvents"); } } } else { Tcl_WrongNumArgs(interp, 1, objv, "?windows | files | timers | idle | all?"); return TCL_ERROR; } while (Tcl_DoOneEvent(flags) != 0) { /* Empty loop body */ } /* Must clear the interpreter's result because event handlers could have executed commands. */ Tcl_ResetResult(interp); return TCL_OK; }