Widget basics
Everything you put on screen is a widget — buttons, labels, entries, frames, and so on. They all share the same small model, described here once; the widget reference pages then list only what's specific to each.
Creating widgets
Create a widget as a child of a container, using the container's factory method:
const frame = app.Frame(); // a frame inside the main window
const btn = frame.Button({ text: 'OK' }); // a button inside that frame
The global app is the main window, and it's a container — so the usual
starting point is app.Something({…}).
Prefer the factory form (
parent.Widget({…})). It parents the widget correctly and keeps it alive as long as its parent lives. You can writenew Button({…}), but then you must keep a reference to it yourself — a widget with no references can be garbage-collected and vanish from the window.
Options are live properties
Every option you can pass to the constructor is also a property you can read and write at any time:
const e = app.Entry({ width: 30 }); // set at creation
e.width = 40; // change later
console.log(e.width); // read
Writing a property updates the widget immediately.
Raw options — .cget / .configure
The camelCase properties cover every option ScriptWeaver surfaces for a widget.
For the long tail — an option with no property (a classic widget's -background,
a seldom-used Tk option) — read it with .cget(name) and write it with
.configure(…):
w.cget('relief'); // read any option (the leading '-' is optional) -> string
w.configure('background', '#1e1e1e'); // write one
w.configure({ relief: 'sunken', borderwidth: 2 }); // or several at once
Prefer the typed property (w.relief = 'sunken') where one exists; reach for
.configure only for what they don't cover. (There is deliberately no .set(…)
— that name is the value-setter on scales, scrollbars and spinboxes.)
Common methods
Every widget inherits these:
| Member | What it does |
|---|---|
.pack / .grid / .place |
Geometry-manager proxies, e.g. w.pack.configure({ fill: 'x' }). See Layout. |
.bind(seq, handler) |
Handle an event, e.g. w.bind('<Double-1>', …). See Events. |
.tooltip(text) |
Show a hover tooltip; .tooltip('') clears it. See Tooltips. |
.focus() |
Give the widget keyboard focus. |
.destroy() |
Remove the widget (and its children). |
.cget(opt) / .configure(…) |
Read / write any option by its raw Tk name (see below). |
.winfo |
Geometry & tree queries: w.winfo.width(), .reqwidth(), .class(), .children(), .parent(), … (see below). |
.wm |
Window-manager ops — title, geometry, … Meaningful on the main window and TopLevel windows: app.wm.title('My App'). |
Inspecting widgets — .winfo and app.byId
.winfo answers questions about a realized widget — its size, position, class,
and place in the tree:
w.winfo.width(); // current size, in pixels
w.winfo.reqwidth(); // requested (natural) size
w.winfo.class(); // 'TButton', 'Frame', …
w.winfo.ismapped(); // is it on screen yet?
w.winfo.children(); // child widgets, as wrappers
w.winfo.parent(); // parent widget, as a wrapper
Sizes read 0 until the widget is mapped; if you need a measurement right after a
change, flush pending layout first with app.update({ idle: true }).
When you hold only a Tk path string — from winfo.children(), a tree row, or
generated code — turn it back into a usable widget with app.byId(path). It
returns the widget (or null if the path isn't a live widget), after which
.cget / .configure / .winfo / .destroy() all work on it.
Tooltips
Any widget can carry a hover tooltip — handy for toolbar/icon buttons:
app.Button({ text: 'Save' }).tooltip('Save the current file (Ctrl+S)');
Pass an empty string to remove it (w.tooltip('')). Tooltips are themed
automatically — they follow app.setTheme() like the rest of the UI.
Global behaviour lives on sw.tooltip:
| Call | Effect |
|---|---|
sw.tooltip.delay(ms) |
Hover delay before a tooltip shows (no argument reads the current value). |
sw.tooltip.enable() / .disable() |
Turn all tooltips on or off. |
sw.tooltip.clear(pattern?) |
Remove tooltips (all, or those matching a widget-path pattern). |
sw.tooltip.configure({ background, foreground, font }) |
Override the balloon style. |
sw.tooltip.fade(bool) |
Fade the balloon in/out where supported. |
The underlying package can also target an individual menu entry, list/tree row, or
notebook tab; reach those via __native_tcl('tooltip', …).
Containers vs. leaf widgets
Some widgets are containers: the main window (app),
Frame, Notebook tabs,
PanedWindow, and others. A container exposes a factory
method for each widget type, so you build a tree by nesting:
const card = app.Frame({ padding: 10 });
card.Label({ text: 'Title' }).pack.configure();
card.Button({ text: 'Go' }).pack.configure();
card.pack.configure({ fill: 'x' });
Leaf widgets — a button, an entry, a label — hold no children.
Reactive variables
For two-way binding — keeping a value and one or more widgets in sync — use a
variable (StringVar, IntVar, BoolVar, DoubleVar) together with a widget's
textVariable or variable option. See Variables & reactivity.
Next
- Layout —
pack,grid,place, and theFlex/Gridhelpers - Events & binding
- Theming — change the look with
app.setTheme() - Widget reference