event(3tk)
π event β no literally, the manual page for event(3tk) β¨
(from the Tk Built-In Commands era, bestie, we love a classic)
πΈ NAME πΈ
event β your miscellaneous little event-facility queen: she defines virtual events and she generates events, and she does it beautifully.
π SYNOPSIS π
event option ?arg ...?
π¦ DESCRIPTION π¦
okay so the event command is literally the girl who handles all your window system event situations π
β like, defining virtual events, and also synthesizing events out of thin air. She's got multiple forms and which one you get depends entirely on what you pass as the first argument. The following forms are currently supported, and yes, we're going through ALL of them:
β¨ event add <<virtual>> sequence ?sequence ...?
Associates the virtual event virtual with the physical event sequence(s) you hand her in the sequence arguments, so the virtual event will trigger whenever any one of those sequences happens. Gorgeous. Obsessed.
virtual can be literally any string value you want, and sequence can be any of the values that are allowed for the sequence argument of the bind command. And here's the cute part: if virtual is already defined, the new physical event sequences just add on to the existing sequences for that event. She's not replacing anything, she's expanding π₯
π event delete <<virtual>> ?sequence sequence ...?
Deletes each of the sequences from the ones associated with the virtual event virtual. Same deal as before β virtual can be any string value, and sequence can be any of the values allowed for the sequence argument to the bind command.
Any sequences that aren't currently associated with virtual? Ignored. Not her problem, she moves on π
And if you provide no sequence argument at all, then all physical event sequences get removed for virtual, which means that virtual event will not trigger anymore. Periodt. It's done. She's clocked out.
π event generate window event ?option value option value ...?
This one generates a window event and arranges for it to be processed exactly as if it had come from the window system. Like, cosplay but make it events.
- window gives the path name of the window the event will be generated for. It can also be an identifier (like the ones returned by
winfo id), as long as it's for a window in the current application. - event gives a basic description of the event, such as
<Shift-Button-2>or<<Paste>>. - If window is empty, the whole screen is meant, and the coordinates are then relative to the screen.
event can be any of the forms allowed for the sequence argument of the bind command β EXCEPT it has to be a single event pattern, not a whole sequence. One pattern only, bestie, we're not doing a whole playlist here.
option-value pairs can specify extra attributes of the event, like the x and y mouse position. (Peep EVENT FIELDS below π)
ok important!! If the-whenoption is not specified, the event gets processed immediately: all of the handlers for the event will complete before theevent generatecommand returns. But if-whenis specified, then that determines when the event is processed.
Also, certain events β like key events β require that the window has focus to receive the event properly. No focus, no keys, she can't hear you π
π event info ?<<virtual>>?
Returns information about virtual events.
- If the
<<virtual>>argument is omitted, the return value is a list of all the virtual events currently defined. - If
<<virtual>>is specified, the return value is a list whose elements are the physical event sequences currently defined for that given virtual event. And if the virtual event isn't defined at all? You get an empty string back. Nothing. Silence. π«Ά
heads up though: virtual events that are not bound to physical event sequences are not returned by event info. Iconic behaviour honestly, but keep it in mind.
π EVENT FIELDS π
Okay so listen bestie π β these are all the lil knobs you can twiddle when you run event generate. Each one maps directly onto a % expansion you'd use in a binding script for the bind command. Same field, same vibe, different spelling. Let's go one by one, no skipping π«Ά
-above windowβ Window sets theabovefield for the event. You can hand it a window path name or an integer window id, dealer's choice β¨. Only valid for Configure events. This one's the%asubstitution in your binding scripts.-borderwidth sizeβ Size has to be a screen distance, and it sets theborder_widthfield. Valid for Configure events only. That's%Bin binding scripts.-button numberβ Number is an integer, and it sets thedetailfield for a Button or ButtonRelease event β and it overrides any button number you already provided in the base event argument, so it wins the fight π . That's%b.-count numberβ Number is an integer; it sets thecountfield. Valid for Expose events.%c, periodt.-data stringβ String can be literally anything, it sets theuser_datafield. Only valid for virtual events, no cap. That's%dfor virtual events in binding scripts.-delta numberβ Number is an integer; it sets thedeltafield for the MouseWheel event. The delta is the direction and the magnitude the mouse wheel got rotated by. Heads up though: this value is not a screen distance, it's units of motion in the mouse wheel, which is such a different vibe π. Typically these come in multiples of 120. Like,120should scroll the text widget up 4 lines and-240would scroll the text widget down 8 lines. But of course other widgets can absolutely define their own behaviors for mouse wheel motion, so don't @ me. This field = the%Dsubstitution.-detail detailβ Detail sets thedetailfield, and it's gotta be one of these icons only, no substitutions:NotifyAncestorNotifyNonlinearVirtualNotifyDetailNoneNotifyPointerNotifyInferiorNotifyPointerRootNotifyNonlinearNotifyVirtual
Valid for Enter, Leave, FocusIn and FocusOut events. Corresponds to %d in binding scripts.
-focus booleanβ Boolean has to be an actual boolean value; it sets thefocusfield. Valid for Enter and Leave events. That's%f.-height sizeβ Size is a screen distance; it sets theheightfield. Valid for Configure events.%h, slay.-keycode numberβ Number is an integer; it sets thekeycodefield. Valid for Key and KeyRelease events.%k.-keysym nameβ Name has to be the name of a valid keysym, likeg,space, orReturn, and its corresponding keycode value gets used as thekeycodefield β which means it overrides any detail you specified in the base event argument π. Valid for Key and KeyRelease events. That's%K.-mode notifyβ Notify sets themodefield and must be one ofNotifyNormal,NotifyGrab,NotifyUngrab, orNotifyWhileGrabbed. Valid for Enter, Leave, FocusIn, and FocusOut events. Corresponds to%m.-override booleanβ Boolean has to be a boolean value; it sets theoverride_redirectfield. Valid for Map, Reparent, and Configure events.%o.-place whereβ Where sets theplacefield and must be eitherPlaceOnToporPlaceOnBottom. Valid for Circulate events.%p.-root windowβ Window is either a window path name or an integer window identifier; it sets therootfield. Valid for Key, KeyRelease, Button, ButtonRelease, Enter, Leave, and Motion events.%R.-rootx coordβ Coord is a screen distance; it sets thex_rootfield. Valid for Key, KeyRelease, Button, ButtonRelease, Enter, Leave, and Motion events.%X.-rooty coordβ Coord is a screen distance; it sets they_rootfield. Valid for Key, KeyRelease, Button, ButtonRelease, Enter, Leave, and Motion events.%Y.-sendevent booleanβ Boolean is a boolean value; it sets thesend_eventfield. Valid for all events, every single one.%E.-serial numberβ Number is an integer; it sets theserialfield. Valid for all events. That's%#.-state stateβ State sets thestatefield. For Key, KeyRelease, Buttons, ButtonRelease, Enter, Leave, and Motion events it has to be an integer value. For Visibility events though, it must be one ofVisibilityUnobscured,VisibilityPartiallyObscured, orVisibilityFullyObscured. Oh and this option overrides any modifiers like Meta or Control you specified in the base event.%s.-subwindow windowβ Window sets thesubwindowfield, either as a path name for a Tk widget or as an integer window identifier. Valid for Key, KeyRelease, Button, ButtonRelease, Enter, Leave, and Motion events. This one's similar to the%Ssubstitution for binding scripts.-time integerβ Integer has to be an integer value; it sets thetimefield. Also, plot twist: the special valuecurrentis allowed, and it gets substituted by the current event time π. Valid for Key, KeyRelease, Button, ButtonRelease, Enter, Leave, Motion, and Property events. Corresponds to%t.-warp booleanβ boolean has to be a boolean value; it says whether the screen pointer should be warped as well. Valid for Key, KeyRelease, Button, ButtonRelease, and Motion events. Now, Tk supports pointer warping relative to the screen's root window, and relative to a Tk window. In that second case, the pointer only warps if the window is mapped, so keep that in mind bestie π.-width sizeβ Size is a screen distance; it sets thewidthfield. Valid for Configure events.%w.-when whenβ When decides when the event actually gets processed, and it has to be one of these:nowβ process the event immediately, before the command even returns. This also happens if you just omit the-whenoption entirely.tailβ place the event on Tcl's event queue behind any events already queued for this application.headβ place the event at the front of Tcl's event queue, so it gets handled before any other events already queued.markβ place the event at the front of Tcl's event queue but behind any other events already queued with-when mark. This one's iconic when you're generating a whole series of events that should be processed in order but at the front of the queue.
-x coordβ Coord is a screen distance; it sets thexfield. Valid for Key, KeyRelease, Button, ButtonRelease, Motion, Enter, Leave, Expose, Configure, Gravity, and Reparent events. Corresponds to%xfor binding scripts. Little extra detail π: ifWindowis empty the coordinate is relative to the screen, and then this option corresponds to the%Xsubstitution instead.-y coordβ Coord is a screen distance; it sets theyfield. Valid for Key, KeyRelease, Button, ButtonRelease, Motion, Enter, Leave, Expose, Configure, Gravity, and Reparent events. Corresponds to%yfor binding scripts. And again, ifWindowis empty the coordinate is relative to the screen, and this option corresponds to the%Ysubstitution.
Okay so here's the tea: any options you don't specify when generating an event get filled with the value0. Every single one... exceptserial, which gets filled with the next X event serial number. β¨
β¨ PREDEFINED VIRTUAL EVENTS β¨
ok so Tk comes with a whole built-in set of virtual events, bestie, you don't even have to make them yourself π Two flavors, and they do different jobs.
First up, the ones Tk defines for the purposes of notification β these are the "hey something happened, go look" events:
<<AltUnderlined>>β this one gets sent to a widget to let it know that the letter it underlined with the-underlineoption (you know, the little accelerator indicator) got pressed together with the Alt key. What you're supposed to do with it is either focus into the widget (or some related widget) or just invoke the widget. Two options, choose your fighter β¨<<Invoke>>β this can be sent to some widgets (likebutton,listbox,menu) as an alternative to<space>. It's giving "press the thing without pressing the spacebar" π<<ListboxSelect>>β sent to alistboxwhen the set of selected item(s) in that listbox gets updated. The selection changed, she's telling you π£<<MenuSelect>>β sent to amenuwhen the currently selected item in the menu changes. It's literally intended for use with context-sensitive help systems, iykyk π<<Modified>>β sent to atextwidget when the contents of the widget are changed.<<Selection>>β sent to atextwidget when the selection in the widget is changed.<<ThemeChanged>>β sent to all widgets when the ttk theme changed. The ttk widgets are listening for this one and they redisplay themselves when it fires. The legacy widgets? They just ignore it entirely, no thoughts head empty π<<TkWorldChanged>>β sent to all widgets when a font is changed, for example by using[font configure]. Theuser_datafield (%d) will have the value"FontChanged". For other system wide changes, this event gets sent to all widgets, and theuser_datafield will indicate the cause of the change. NOTE: all tk and ttk widgets already handle this event internally. so like, you don't have to do anything, but now you know π«Ά<<TraverseIn>>β sent to a widget when the focus enters the widget because of a user-driven "tab to widget" action.<<TraverseOut>>β sent to a widget when the focus leaves the widget because of a user-driven "tab to widget" action.<<UndoStack>>β sent to atextwidget when its undo stack or redo stack becomes empty or unempty. (yes, "unempty" is a word here, we don't make the rules π)<<WidgetViewSync>>β sent to atextwidget when its internal data become obsolete, and again when those internal data are back in sync with the widget view. Thedetailfield (the%dsubstitution) is either true (when the widget is in sync) or false (when it is not).
and then there's the second group π Tk defines these following virtual events for the purposes of unifying bindings across multiple platforms. Users expect them to behave in the following way, so here's the whole roster:
<<Clear>>β delete the currently selected widget contents.<<Copy>>β copy the currently selected widget contents to the clipboard.<<Cut>>β move the currently selected widget contents to the clipboard.<<LineEnd>>β move to the end of the line in the current widget while deselecting any selected contents.<<LineStart>>β move to the start of the line in the current widget while deselecting any selected contents.<<NextChar>>β move to the next item (i.e., visible character) in the current widget while deselecting any selected contents.<<NextLine>>β move to the next line in the current widget while deselecting any selected contents.<<NextPara>>β move to the next paragraph in the current widget while deselecting any selected contents.<<NextWord>>β move to the next group of items (i.e., visible word) in the current widget while deselecting any selected contents.<<Paste>>β replace the currently selected widget contents with the contents of the clipboard.<<PasteSelection>>β insert the contents of the selection at the mouse location. (this event has meaningful%xand%ysubstitutions, so you actually get coordinates πΈ)<<PrevChar>>β move to the previous item (i.e., visible character) in the current widget while deselecting any selected contents.<<PrevLine>>β move to the previous line in the current widget while deselecting any selected contents.<<PrevPara>>β move to the previous paragraph in the current widget while deselecting any selected contents.<<PrevWindow>>β traverse to the previous window.<<PrevWord>>β move to the previous group of items (i.e., visible word) in the current widget while deselecting any selected contents.<<Redo>>β redo one undone action.<<SelectAll>>β set the range of selected contents to the complete widget.<<SelectLineEnd>>β move to the end of the line in the current widget while extending the range of selected contents.<<SelectLineStart>>β move to the start of the line in the current widget while extending the range of selected contents.<<SelectNextChar>>β move to the next item (i.e., visible character) in the current widget while extending the range of selected contents.<<SelectNextLine>>β move to the next line in the current widget while extending the range of selected contents.<<SelectNextPara>>β move to the next paragraph in the current widget while extending the range of selected contents.<<SelectNextWord>>β move to the next group of items (i.e., visible word) in the current widget while extending the range of selected contents.<<SelectNone>>β reset the range of selected contents to be empty.<<SelectPrevChar>>β move to the previous item (i.e., visible character) in the current widget while extending the range of selected contents.<<SelectPrevLine>>β move to the previous line in the current widget while extending the range of selected contents.<<SelectPrevPara>>β move to the previous paragraph in the current widget while extending the range of selected contents.<<SelectPrevWord>>β move to the previous group of items (i.e., visible word) in the current widget while extending the range of selected contents.<<ToggleSelection>>β toggle the selection.<<Undo>>β undo the last action.
ok that was a lot but you survived it, so proud of you genuinely π₯Ήπ
π EXAMPLES π
π MAPPING KEYS TO VIRTUAL EVENTS π
so for a virtual event binding to actually trigger, two things have to happen, and neither is optional:
- the virtual event has to be defined with the
event addcommand - a binding has to be created for that virtual event with the
bindcommand
Consider the following virtual event definitions:
event add <<Paste>> <Control-y>
event add <<Paste>> <Button-2>
event add <<Save>> <Control-X><Control-S>
event add <<Save>> <Shift-F12>
if {[tk windowingsystem] eq "aqua"} {
event add <<Save>> <Command-s>
}
In the bind command, a virtual event can be bound like any other builtin event type, like this:
bind Entry <<Paste>> {%W insert [selection get]}
The double angle brackets are how you specify that a virtual event is being bound β that's the tell π So if the user types Control-y or presses button 2, or if a <<Paste>> virtual event is synthesized with event generate, then the <<Paste>> binding will be invoked. slay.
but here's the tea π΅ If a virtual binding has the exact same sequence as a separate physical binding, then the physical binding takes precedence. Consider the following example:
event add <<Paste>> <Control-y> <Meta-Control-y>
bind Entry <Control-y> {puts Control-y}
bind Entry <<Paste>> {puts Paste}
When the user types Control-y, the <Control-y> binding gets invoked, because a physical event is considered more specific than a virtual event β all other things being equal. However, when the user types Meta-Control-y, the <<Paste>> binding gets invoked, because the Meta modifier in the physical pattern associated with the virtual binding is more specific than the <Control-y> sequence for the physical event. it's giving specificity war and the modifiers are winning π
Bindings on a virtual event may be created before the virtual event exists. In fact, the virtual event never actually needs to be defined at all β for instance, on platforms where that specific virtual event would be meaningless or ungeneratable. so go ahead and bind that imaginary event, she's valid β¨
When a definition of a virtual event changes at run time, all windows will respond immediately to the new definition. Starting from the preceding example, if the following code is executed:
bind Entry <Control-y> {}
event add <<Paste>> <F6>
the behavior will change in two ways:
- First, the shadowed
<<Paste>>binding will emerge. Typing Control-y will no longer invoke the<Control-y>binding, but instead invoke the virtual event<<Paste>>. - Second, pressing the F6 key will now also invoke the
<<Paste>>binding.
ok that's genuinely iconic behavior, she reinvented herself π
π¦ MOVING THE MOUSE POINTER π¦
Sometimes it is useful to be able to really move the mouse pointer. Like, for example, if you have some software that's capable of demonstrating directly to the user how to use the program. To do this, you need to "warp" the mouse around by using event generate, like this:
for {set xy 0} {$xy < 200} {incr xy} {
event generate . <Motion> -x $xy -y $xy -warp 1
update
after 50
}
Note that it is usually considered bad style to move the mouse pointer for the user, because it removes control from them. Therefore this technique should be used with caution. Also note that it is not guaranteed to function on all platforms. π
so yeah, moving someone's cursor is a little rude, do it at your own risk bestie π
π SEE ALSO π
π KEYWORDS π
event, binding, define, handle, virtual event
that's the whole page bb, you made it to the end π₯³π this was the Tk 8.3 edition of event(3tk) β go forth and bind things, you absolute main character, periodt β¨ππ
π¦ where this page comes from
- ubuntu stonking: tk9.0-doc 9.0.4-1
- Copyright (c) 1996 Sun Microsystems, Inc
- Copyright (c) 1998-2000 Ajuba Solutions
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms