Skip to content

PageStack

PageStack is a stacked view container that manages multiple "pages" where only one page is visible at a time.

It provides history-based navigation (push, back, forward), similar to a web browser, making it ideal for wizards, multi-step workflows, and task-based navigation inside a single window.


Quick start

Create a PageStack, add pages, and navigate between them:

import bootstack as bs

app = bs.App()

stack = bs.PageStack(app, padding=10)
stack.pack(fill="both", expand=True)

page1 = stack.add("start", padding=10)
page2 = stack.add("details", padding=10)
page3 = stack.add("confirm", padding=10)

bs.Label(page1, text="Start page").pack()
bs.Button(page1, text="Next", command=lambda: stack.navigate("details")).pack()

bs.Label(page2, text="Details page").pack()
bs.Button(page2, text="Next", command=lambda: stack.navigate("confirm")).pack()
bs.Button(page2, text="Back", command=stack.back).pack()

bs.Label(page3, text="Confirm page").pack()
bs.Button(page3, text="Back", command=stack.back).pack()

app.mainloop()

When to use

Use PageStack when:

  • navigation is sequential or flow-based

  • back/forward behavior improves usability

  • only one view should be visible at a time

Consider a different control when:

  • users need random access to views - use Notebook instead

  • the interaction model is "switch categories" - use Notebook instead

  • multiple views must be visible simultaneously - use PanedWindow instead


Appearance

Styling

PageStack itself is a container without visual styling. Style the individual pages and navigation controls as needed.


Examples and patterns

Pages are keyed

Each page is identified by a unique string key:

stack.add("settings")
stack.navigate("settings")

Keys are stable and preferable to index-based navigation.

Adding pages

Use add() to get a page frame for placing widgets.

page = stack.add("profile", padding=10)

Frame options (padding, color, etc.) can be passed directly:

page = stack.add("settings", padding=10, accent="primary")

Or add an existing widget as a page:

frame = bs.Frame(stack, padding=10)
stack.add("custom", frame)

Navigate to a page (push):

stack.navigate("details")

Move through history:

stack.back()
stack.forward()

Check availability:

stack.can_back()
stack.can_forward()

Redirect (replace current history entry):

stack.navigate("login", replace=True)

Passing data between pages

Pass a dict when navigating:

stack.navigate("confirm", data={"user": user_id})

That data is included in lifecycle event payloads so pages can react to it.

Full-bleed pages

Pages automatically fill the entire stack using pack layout with fill='both' and expand=True. To control layout, use pack or grid on the page contents themselves:

page = stack.add("full")
bs.Label(page, text="This page fills the stack").pack(fill="both", expand=True)

Removing pages

Remove a page entirely:

stack.remove("details")

If the removed page is active, the stack becomes empty until you navigate elsewhere.

Events

PageStack emits a navigation lifecycle you can hook into:

  • <<PageUnmount>> - current page is being hidden

  • <<PageWillMount>> - new page will be shown

  • <<PageMount>> - new page is now visible

  • <<PageChange>> - navigation completed

def on_page_changed(event):
    data = event.data
    print(data["page"], data["nav"])

funcid = stack.on_page_changed(on_page_changed)
# stack.off_page_changed(funcid)

Event payload

Navigation events include:

  • page - current page key

  • prev_page - previous page key

  • prev_data - data passed to the previous page

  • nav - "push", "back", or "forward"

  • index - current history index

  • length - total history length

  • can_back - whether back navigation is possible

  • can_forward - whether forward navigation is possible


Behavior

UX guidance

  • Use PageStack for linear or stateful navigation

  • Provide clear Back/Next controls when history is involved

  • Avoid mixing PageStack flow navigation with tabs (Notebook) in the same region

Think like a flow

PageStack works best when users think in terms of steps or screens, not categories.


Additional resources

API reference