blt::busy(3tcl)
blt::busy πβ¨
okay bestie, this is the blt::busy page from the BLT Built-In Commands manual, section 3tcl. it's the girlies' guide to making Tk widgets busy and telling the user "not rn, we're processing π
". no cap, it's genuinely one of the most useful little commands out there.
β¨ NAME β¨
busy β make Tk widgets busy, temporarily blocking user interactions. it's giving "do not perceive me" but for a whole widget hierarchy π«Ά
β¨ SYNOPSIS β¨
busy hold window ?option value?...
busy release window ?window?...
busy configure window ?option value?...
busy forget window ?window?...
busy isbusy ?pattern?
busy names ?pattern?
busy status window
β¨ DESCRIPTION β¨
the busy command is the simple, low-effort, high-impact way to block keyboard, button, and pointer events from reaching Tk widgets β and on top of that, it overrides the widget's cursor with a configurable busy cursor. iconic behaviour, honestly. β¨
πΈ INTRODUCTION πΈ
there are SO many times in an app where you just need to temporarily restrict what the user can do. like. say your app has a "run" button, and pressing it kicks off some processing. while the app is busy processing, you probably don't want the user clicking "run" again π. and you might also want to stop them from doing other stuff, like clicking a "print" button.
the busy command lets you make Tk widgets busy. meaning: user interactions like button clicks, moving the mouse, typing at the keyboard, etc. β the widget just ignores all of it. and you can set a special cursor (like a watch) that overrides the widget's normal cursor, so the user gets that feedback that the app (widget) is temporarily busy. it's giving β¨communicationβ¨.
when a widget is made busy, the widget and all of its descendants will ignore events. and the way it makes an entire panel of widgets busy is so easy β you just make the toplevel widget (like ".") busy. that's easier and far much more efficient than recursively traversing the widget hierarchy, disabling each widget and re-configuring its cursor. we do not do the recursive traversal grind here, bestie. π§
ngl, busy can often be used instead of Tk's grab command. unlike grab, which restricts all user interactions to one widget, with busy you can have more than one widget active β for example, a "cancel" dialog and a "help" button. main character energy for multiple widgets at once π
π EXAMPLE π
you can make several widgets busy by simply making its ancestor widget busy using the hold operation.
frame .top
button .top.button; canvas .top.canvas
pack .top.button .top.canvas
pack .top
. . .
busy hold .top
update
all the widgets within .top (including .top) are now busy. and using update insures that busy command will take effect before any other user events can occur. slay. π₯
when the application is no longer busy processing, you can allow user interactions again by the release operation.
busy release .top
the busy window has a configurable cursor. you can change the busy cursor using the configure operation.
busy configure .top -cursor "watch"
finally, when you no longer need to the busy window, invoke the forget operation to free any resources it allocated.
busy forget .top
destroying the widget will also clean up any resources allocated by the busy command. so it's self-cleaning, we love a low-maintenance queen π
π OPERATIONS π
the following operations are available for the busy command:
busy hold window ?option value?...β makes the widget window (and its descendants in the Tk window hierarchy) busy. window must be a valid path name of a Tk widget. the busy window is mapped the next time idle tasks are processed, and the widget and its descendants will be blocked from user interactions. all events in the widget window and its descendants are ignored. normallyupdateshould be called immediately afterward to insure that theholdoperation is in effect before the application starts its processing. the following configuration options are valid:-cursorcursorName β specifies the cursor to be displayed when the widget is made busy. cursorName can be in any form accepted byTk_GetCursor. the default cursor iswatch. β
busy configure window ?option value?...β queries or modifies thebusycommand configuration options for window. window must be the path name of a widget previously made busy by theholdoperation. if no options are specified, a list describing all of the available options for window is returned (seeTk_ConfigureInfofor information on the format of this list). if option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). if one or more option-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns the empty string. option may have any of the values accepted by theholdoperation.
okay so please note: the option database is referenced through window. for example, if the widget.frameis to be made busy, the busy cursor can be specified for it by either option command:tcl option add *frame.busyCursor gumby option add *Frame.BusyCursor gumby
busy forget window ?window?...β releases resources allocated by thebusycommand for window, including the busy window. user events will again be received again by window. resources are also released when window is destroyed. window must be the name of a widget specified in theholdoperation, otherwise an error is reported. β οΈbusy isbusy ?pattern?β returns the pathnames of all widgets that are currently busy. if a pattern is given, the path names of busy widgets matching pattern are returned.busy names ?pattern?β returns the pathnames of all widgets that have previously been made busy (i.e. a busy window is allocated and associated with the widget). it makes no difference if the window is currently busy or not. if a pattern is given, the path names of busy widgets matching pattern are returned.busy release window ?window?...β restores user interactions to the widget window again. this differs from theforgetoperation in that the busy window is not destroyed, but simply unmapped. window must be the name of a widget specified in aholdoperation, otherwise an error is reported. β οΈbusy status windowβ returns the status of a widget window previously made busy. an error is reported if window was never made busy, or theforgetoperation was invoked (i.e. does not currently have a busy window associated with it). if window is presently can not receive user interactions,1is returned, otherwise0. π«Ά
π¦ BINDINGS π¦
the event blocking feature is implemented by creating and mapping a transparent window that completely covers the widget. when the busy window is mapped, it invisibly shields the widget and its hierarchy from all events that may be sent. like Tk widgets, busy windows have widget names in the Tk window hierarchy. this means that you can use the bind command, to handle events in the busy window.
busy hold .frame.canvas
bind .frame.canvas_Busy <Enter> { ... }
normally the busy window is a sibling of the widget. the name of the busy window is "widget_Busy" where widget is the name of the widget to be made busy. in the previous example, the pathname of the busy window is ".frame.canvas_Busy". the exception is when the widget is a toplevel widget (such as ".") where the busy window can't be made a sibling. the busy window is then a child of the widget named "widget._Busy" where widget is the name of the toplevel widget. in the following example, the pathname of the busy window is "._Busy".
busy hold .
bind ._Busy <Enter> { ... }
π ENTER/LEAVE EVENTS π
mapping and unmapping busy windows generates Enter/Leave events for all widgets they cover. please note this if you are tracking Enter/Leave events in widgets. like, just be aware bestie π
π KEYBOARD EVENTS π
when a widget is made busy, the widget is prevented from gaining the keyboard focus by the busy window. but if the widget already had focus, it still may received keyboard events. to prevent this, you must move focus to another window.
busy hold .frame
label .dummy
focus .dummy
update
the above example moves the focus from .frame immediately after invoking the hold so that no keyboard events will be sent to .frame or any of its descendants. dummy label as a focus decoy?? that's the move, fr fr π
β KEYWORDS β
busy, keyboard events, pointer events, window, cursor
and that's the whole page, bestie!! this is from BLT, version 2.5, and the page is blt::busy(3tcl). go forth and make things busy πβ¨π
π¦ where this page comes from
- debian bookworm: blt-dev 2.5.3+dfsg-4.1
- debian trixie: blt-dev 2.5.3+dfsg-8
- ubuntu jammy: blt-dev 2.5.3+dfsg-4.1build2
- ubuntu noble: blt-dev 2.5.3+dfsg-7build1
- ubuntu questing: blt-dev 2.5.3+dfsg-8
- ubuntu resolute: blt-dev 2.5.3+dfsg-8build1
- ubuntu stonking: blt-dev 2.5.3+dfsg-9
- Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms