Skip to content

Events & Bindings

Tk delivers user input and system notifications through an event and binding system. Understanding how events are generated, propagated, and handled is essential for building predictable interfaces with bootstack.

This page focuses on how Tk events work and how bootstack expects you to use them. See Guides โ†’ Reactivity for higher-level reactive patterns.


What an event is

An event represents something that happened:

  • a mouse button was pressed or released
  • a key was pressed
  • a window was resized or exposed
  • focus changed
  • a timer fired

Events are identified by event sequences, such as:

  • <Button-1>
  • <KeyPress>
  • <Configure>
  • <<VirtualEvent>>

When an event occurs, Tk determines which bindings should run.


Binding events to widgets

Events are typically bound to widgets using bind:

widget.bind("<Button-1>", on_click)

Bindings associate an event sequence with a callback. The callback is invoked when the event is delivered to the widget.

Bindings can be attached at different scopes:

  • widget bindings: apply only to a specific widget
  • class bindings: apply to all widgets of a given class
  • application bindings: apply to all widgets in the application

bootstack does not change this model, but it encourages explicit, localized bindings rather than global ones when possible.


Event propagation

Events in Tk propagate through a sequence of bindtags.

Each widget has an ordered list of bindtags that determine where bindings are looked up. Typical bindtags include:

  • the widget instance
  • the widget class
  • the toplevel window
  • the application

When an event occurs, Tk processes bindings in bindtag order until propagation stops.

Understanding propagation is critical when debugging unexpected behavior.


Stopping propagation

Callbacks may stop event propagation by returning the string "break":

def on_click(event):
    do_something()
    return "break"

This prevents later bindings from running.

Use this carefully: stopping propagation can interfere with expected widget behavior if overused.


Virtual events

Virtual events are user-defined events identified by names like:

<<ItemSelected>>
<<DataChanged>>

Virtual events allow you to decouple what happened from how it was triggered.

They are especially useful when:

  • multiple inputs should trigger the same behavior
  • application-level state changes need to notify many components

bootstack strongly encourages virtual events for semantic communication. See Capabilities โ†’ Virtual Events for the framework's virtual event patterns.


bootstack's guidance on events

bootstack treats events as a low-level mechanism:

  • use direct bindings for immediate UI interactions
  • use virtual events for semantic signals
  • avoid deeply nested binding logic

For application state and data flow, prefer Signals over raw events.


Common pitfalls

  • binding too many global events
  • relying on implicit propagation order
  • mixing state mutation and UI effects in callbacks
  • overusing "break"

Clear event boundaries lead to more maintainable applications.


Next steps