Layout Widgets¶
TopLevel¶
The root-level container widget. Uses absolute positioning and attaches to the document body. Typically the outermost widget in a pgwidgets application.
Constructor: new Widgets.TopLevel({title, icon, resizable,
moveable, closeable, minimizable, maximizable, lowerable,
shadeable})
Options:
title– title bar text (enables the title bar when set).icon– URL ordata:URI shown at the left edge of the title bar. Defaults tonull(hidden).resizable– enable corner resize grips.moveable– allow dragging by the title bar (defaults totruewhentitleis set).closeable– show close button (defaulttrue).minimizable– show minimize button (defaultfalse). Minimized windows auto-stack along the bottom of the viewport.maximizable– show maximize button (defaultfalse). Maximize fills the browser viewport (snapshot at click time; doesn’t follow viewport resizes).lowerable– show send-to-back button (defaultfalse).shadeable– allow rolling up to just the title bar (defaulttrue). Available from the right-click context menu and via double-click on the title bar.
Methods:
Method |
Description |
|---|---|
|
Set the single child widget (fills the entire area). |
|
Set position in pixels. |
|
Set or create the title bar text. |
|
Set or clear the title-bar icon. Pass |
|
Enable or disable title bar dragging. |
|
Bring to the front / send to the back (z-order). |
|
Switch the named state on or off. |
|
Canonical state setter / getter. States are |
Callbacks:
move– fired when the widget is dragged to a new position.close– fired when the close button is clicked.window-state– fires with the new state name when minimize / maximize / shade transitions occur. The Python side wraps this inWIDGET_CALLBACK_SYNCso the state survives reconnect.
Window controls:
Title-bar buttons appear only for the options enabled at construction. The right-click context menu lists the applicable actions (Raise, Lower, Shade, Minimize, Maximize, Close) and supports both click-release and press-drag-release styles, like a menubar. Title-bar drag and corner-grip resize are bound to the left mouse button (button 0) so right-click and middle-click are free for other gestures.
let top = new Widgets.TopLevel({
title: "My App", icon: "/icons/app.svg",
resizable: true,
minimizable: true, maximizable: true,
lowerable: true, shadeable: true,
});
top.resize(800, 600);
let vbox = new Widgets.VBox({spacing: 8});
// ... add widgets to vbox ...
top.set_widget(vbox);
top.show();
top.add_callback('close', () => top.hide());
VBox¶
Vertical box layout. Children are stacked top to bottom.
Constructor: new Widgets.VBox()
Methods:
Method |
Description |
|---|---|
|
Add a child widget. stretch (0 or 1) controls whether it expands. |
|
Set spacing between children in pixels. |
Callbacks: child-added, child-removed (from ContainerWidget).
let vbox = new Widgets.VBox();
vbox.set_spacing(8);
vbox.set_padding(10);
vbox.add_widget(label, 0); // fixed size
vbox.add_widget(editor, 1); // stretches to fill
HBox¶
Horizontal box layout. Children are placed left to right.
Constructor: new Widgets.HBox()
Methods:
Method |
Description |
|---|---|
|
Add a child widget. stretch controls whether it expands. |
|
Set spacing between children in pixels. |
Callbacks: child-added, child-removed.
let hbox = new Widgets.HBox();
hbox.set_spacing(4);
hbox.add_widget(button1, 0);
hbox.add_widget(button2, 0);
Expanding size policy¶
Beyond Box’s per-child stretch argument, every widget carries
an expanding policy that any container respects. This mirrors Qt’s
QSizePolicy.Expanding and is the simplest way to say “this widget
should fill the space it’s given” without caring which container it
ends up in.
Signature: widget.set_expanding(horizontal=false, vertical=false)
Both flags default to False. Each one asks the widget to grow
into the available space along that axis. Concretely, on the
requested axes the call writes flex: 1 1 auto, align-self:
stretch, min-{width,height}: 0 and {width,height}: 100%,
which works inside any flex parent (Box, Splitter, TabWidget
content, ScrollArea, Frame, …) and also inside a non-flex
parent.
Typical patterns:
// Image fills its tab page in both directions
img.set_expanding(true, true);
tab.add_tab(img, "Frames");
// Status label stretches horizontally but stays its natural height
label.set_expanding(true, false);
hbox.add_widget(label); // stretch=0; expanding still wins
// Vertical sidebar fills the column but keeps its natural width
sidebar.set_expanding(false, true);
Order independence. set_expanding may be called either before
or after the widget is added to its parent. The flags are stored on
the widget and Box.add_widget consults them as a fallback when
its own stretch argument is 0; calling set_expanding after
the widget is already parented simply rewrites the inline CSS to
match.
Interaction with Box stretch. When add_widget(child, stretch=N)
is called with N > 0, the explicit stretch wins over
set_expanding on the main axis — it’s the more specific
per-container override and also carries a proportion (stretch=2
vs. stretch=1 for proportional growth). set_expanding still
controls the cross axis and any non-Box parents.
Image with use_animation_frame. A canvas’s intrinsic size is its
drawing-buffer (width/height attributes), so without an
explicit policy it lays out at the bitmap size and may collapse to
0×0 inside a non-stretch container (e.g. a fresh tab page). Call
set_expanding(true, true) to make it fill, or
set_min_size(w, h) to pin a specific size — both work directly
on the Image, no wrapper container required.
GridBox¶
Grid layout with row/column placement.
Constructor: new Widgets.GridBox({rows, columns})
Options:
rows– number of rowscolumns– number of columns
Methods:
Method |
Description |
|---|---|
|
Place a child at the given row and column. |
|
Set vertical spacing between rows. |
|
Set horizontal spacing between columns. |
|
Set both row and column spacing. |
|
Return |
|
Return the widget at a given cell. |
|
Insert a row at index with optional widgets. |
|
Append a row with optional widgets. |
|
Delete row at index. |
|
Insert a column at index. |
|
Append a column. |
|
Delete column at index. |
Callbacks: child-added, child-removed.
let grid = new Widgets.GridBox({rows: 2, columns: 3});
grid.set_spacing(4);
grid.add_widget(label, 0, 0);
grid.add_widget(entry, 0, 1);
FixedLayout¶
Simple absolute-positioning container. Children are placed at fixed
(x, y) pixel offsets within the container and rendered at their
natural size unless resize() has been called on them, in which
case the explicit size sticks. Useful for static panels with
hand-laid widgets — HUDs, calibration overlays, fixed-position forms.
Constructor: new Widgets.FixedLayout()
Options: (none)
Methods:
Method |
Description |
|---|---|
|
Add child at the given pixel offset from the container’s content edge. |
|
Remove child; optionally destroy it. Inherited from
|
|
Remove every child. |
Callbacks: child-added, child-removed.
let panel = new Widgets.FixedLayout();
panel.add_widget(new Widgets.Label("Status"), 8, 8);
let ok = new Widgets.Button("OK");
ok.resize(80, 28); // explicit size — overrides natural
panel.add_widget(ok, 8, 40);
Splitter¶
Resizable split pane (horizontal or vertical).
Constructor: new Widgets.Splitter({orientation})
Options:
orientation–"horizontal"(default) or"vertical"
Methods:
Method |
Description |
|---|---|
|
Add a pane. |
|
Set pane sizes as an array of pixel values. |
|
Return current pane sizes. |
|
Set minimum size for a pane. |
Callbacks:
child-added,child-removed– container child events.sizing– fired when pane sizes change.
let splitter = new Widgets.Splitter({orientation: "horizontal"});
splitter.add_widget(leftPanel);
splitter.add_widget(rightPanel);
splitter.set_sizes([200, 400]);
TabWidget¶
Tabbed container with switchable pages.
Constructor: new Widgets.TabWidget({closable, reorderable, tab_position})
Options:
closable– show close buttons on tabsreorderable– allow tab drag reorderingtab_position– tab bar position ("top","bottom","left","right")
Methods:
Method |
Description |
|---|---|
|
Add a tab. options can include |
|
Switch to the tab containing child. |
|
Close the tab containing child. |
|
Switch to tab by index. |
|
Return current tab index. |
|
Return the tab ID for a child. |
|
Return the child for a tab ID. |
|
Return the index of a child’s tab. |
|
Highlight a tab with a background color. |
|
Change tab bar position. |
Callbacks:
child-added,child-removed– container child events.page-switch– fired when the active tab changes. Handler receives(widget, child, index).page-close– fired when a tab close button is clicked.
let tabs = new Widgets.TabWidget({closable: true, tab_position: "top"});
tabs.add_widget(page1, {title: "First"});
tabs.add_widget(page2, {title: "Second"});
tabs.add_callback('page-switch', (w) => console.log("switched"));
StackWidget¶
Stacked pages without tab headers. Only one page is visible at a time.
Constructor: new Widgets.StackWidget()
Methods:
Method |
Description |
|---|---|
|
Add a page. |
|
Show a specific page. |
|
Show page by index. |
|
Return current page index. |
Callbacks:
child-added,child-removed– container child events.page-switch– fired when the visible page changes.page-close– fired when a page is closed.
ScrollArea¶
Scrollable viewport wrapping a single child widget.
Constructor: new Widgets.ScrollArea({hscrollbar, vscrollbar})
Options:
hscrollbar– horizontal scrollbar policyvscrollbar– vertical scrollbar policy
Methods:
Method |
Description |
|---|---|
|
Set the scrollable content widget. |
Callbacks: scrolled.
Frame¶
Titled border container for grouping widgets.
Constructor: new Widgets.Frame({title})
Options:
title– frame title text
Methods:
Method |
Description |
|---|---|
|
Set the content widget. |
|
Change the frame title. |
Callbacks: None.
let frame = new Widgets.Frame({title: "Settings"});
frame.set_widget(settingsPanel);
Expander¶
Collapsible section with a clickable header.
Constructor: new Widgets.Expander({title, collapsible, shadow})
Options:
title– header textcollapsible– whether the section can collapseshadow– show drop shadow
Methods:
Method |
Description |
|---|---|
|
Set the content widget. |
|
Toggle collapsed/expanded state. |
Callbacks: toggled – fired when the section is collapsed or expanded.
MDIWidget¶
Multiple Document Interface workspace with draggable, resizable sub-windows.
Constructor: new Widgets.MDIWidget()
Methods:
Method |
Description |
|---|---|
|
Add a sub-window. options:
|
|
Arrange sub-windows in a cascade. |
|
Tile sub-windows to fill the workspace. |
|
Return the sub-window object for a child. |
|
Return |
|
Close a sub-window. |
|
Set edge resistance for sub-window dragging. |
|
Return content widgets (not sub-windows). |
|
Return the MDISubWindow objects. |
|
Move a child’s sub-window. |
|
Resize a child’s sub-window. |
|
Return |
|
Return |
|
Return the index of a child. |
|
Return the child at an index. |
Sub-window methods (via get_subwin(child)):
Method |
Description |
|---|---|
|
Change the sub-window title text. |
|
Move the sub-window to the given position. |
|
Alias for set_position. |
|
Bring sub-window to front / send to back within the workspace. |
|
Switch between normal and minimized / maximized states. |
|
Roll up to just the title bar in place (only effective
when |
Active sub-window highlight: the topmost sub-window’s title bar
is drawn slightly lighter (CSS class .mdi-active), like the
active tab in a TabWidget. This updates automatically as
raise_() / lower() are called or sub-windows are added /
removed.
Right-click context menu: title-bar right-click pops a menu
with Raise, Lower, Shade (when shadeable), Minimize, Maximize,
and Close. Same press-drag-release semantics as the menubar.
Callbacks:
child-added,child-removed– container child events.page-switch– fired when the active sub-window changes.page-close– fired when a sub-window is closed.scrolled– fired when the workspace is scrolled.
let mdi = new Widgets.MDIWidget();
mdi.add_widget(editor1, {title: "Document 1", x: 10, y: 10});
mdi.add_widget(editor2, {title: "Document 2", x: 50, y: 50});
mdi.tile_windows();
// Change a sub-window title later
let subwin = mdi.get_subwin(editor1);
subwin.set_title("Document 1 (modified)");
// Query sub-window configuration
let config = mdi.get_configuration(editor1);
// config = {x: ..., y: ..., width: ..., height: ..., title: "..."}