Widgets#
Widgets extend Tkinter with compound components. Import from VIStk.Widgets.
TabBar#
TabBar(Frame) — A row of clickable tabs displayed at the top of a TabManager. Each tab
has a label button and a close button (✕). A thin vertical separator divides adjacent tabs. Tabs
can be reordered by dragging, detached into their own window, or merged into another TabBar.
TabBar is created automatically by TabManager.__init__ and exposed as
host.TabManager.tab_bar. You do not normally need to interact with it directly.
Interaction model#
Action |
Behaviour |
|---|---|
Click |
Focuses the tab. |
Close button (✕) |
Closes the tab. |
Right-click |
Context menu with Open in new window, Force refresh, and Close. |
Drag (≥ 8 px) |
Shows a semi-transparent ghost window following the cursor; a thin blue insertion indicator appears in the hovered bar showing where the tab will land. |
Release over the same bar |
Reorders the tab to the indicated position. |
Release over another bar |
Merges the tab into that bar. |
Release outside all bars |
Detaches the tab into a new |
Attributes#
Attribute |
Type |
Description |
|---|---|---|
|
|
Name of the currently focused tab. |
|
|
The |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Methods#
Method |
Returns |
Description |
|---|---|---|
|
|
Add a tab. Does nothing if already open. Returns |
|
|
Remove the tab. Returns |
|
|
Set |
|
|
Return whether a tab with |
|
|
Return the 0-based position, or |
|
— |
Show the blue insertion indicator at position |
|
— |
Hide the insertion indicator. |
|
— |
Deregisters from |
Registry#
All live TabBar instances are tracked in VIStk.Widgets._TabBar._TABBAR_REGISTRY. This
list is used during drag motion to detect cross-bar merges.
SplitView#
SplitView(Frame) — A tree-of-panes container that allows the Host (or DetachedWindow) content
area to be divided into multiple panes, each with its own TabManager and TabBar. Panes are
separated by draggable sashes.
Each SplitView instance holds a root widget that is either a single TabManager (no split)
or a _SplitNode wrapping a ttk.PanedWindow with two child slots. Each slot is either a
TabManager (leaf) or another _SplitNode (branch), forming an arbitrary binary tree.
Import: from VIStk.Widgets._SplitView import SplitView
Key methods#
Method |
Description |
|---|---|
|
Split pane into two side-by-side panes. direction is |
|
Collapse pane out of the tree, promoting the surviving sibling. If the root becomes a
single |
|
Walk the tree and return all leaf |
|
Aggregate |
|
Locate which |
|
Store a callback dict and apply to all current and future |
Focus tracking#
focused_pane(property) — theTabManagerthe user last interacted with.Clicking anywhere inside a pane (including child widgets like buttons) sets that pane as focused via a toplevel-level
<Button-1>binding._global_focused_pane(class attribute) — tracks the last-focused pane across all windows (Host and DetachedWindows). Used byHost._open_tab()to open new tabs in the correct pane.When a window loses OS focus, all pane focus indicators dim. They restore on
<FocusIn>.
Drag-to-split#
Dragging a tab into the outer 25% of any pane’s content area shows a translucent blue overlay (
Toplevelwithalpha=0.22) indicating the split direction.Dragging to the center shows a full-pane overlay; dropping there adds the tab to that pane.
detect_drop_zone(x_root, y_root)— returns(pane, direction)orNone.detect_any_drop_zone(x_root, y_root)— class method that checks all registered SplitViews, respecting window z-order viawm stackorder.lift_window_at(x_root, y_root)— class method that lifts the target window to the front when the cursor enters its non-overlapping area during a drag.
Cross-window support#
All live SplitView instances are tracked in SplitView._registry (class-level list).
This enables cross-window drag-to-split: a tab dragged from one window can be dropped into a
split zone in another window.
When windows overlap, only the frontmost window at the cursor position shows drop zones.
The stacking order is determined by Tk’s wm stackorder command.
InfoRow#
InfoRow(Frame) — A slim status bar packed at the bottom of the Host window. Created
automatically by Host.__init__ and exposed as host.InfoRow.
Zone |
Content |
|---|---|
Left |
Active screen name and version, updated on tab focus change. |
Centre |
Project copyright string (static, set at startup). |
Right |
App version and live FPS counter, e.g. |
The copyright string is normalised at construction: if it does not already contain ©, the
current year and © are automatically prepended.
Methods#
Method |
Description |
|---|---|
|
Update the screen label. Pass empty strings to clear. |
|
Update the FPS counter. Called by |
InfoRow is managed entirely by Host — you do not need to call its methods directly.
ScrollableFrame#
ScrollableFrame(ttk.Frame) — A frame with a vertical scrollbar. Content is placed inside
scrollable_frame. Mouse wheel scrolling activates when the cursor enters the frame and
deactivates when it leaves.
from VIStk.Widgets import ScrollableFrame
sf = ScrollableFrame(parent)
sf.pack(fill=BOTH, expand=True)
# Place content inside scrollable_frame, not sf directly
Label(sf.scrollable_frame, text="Item 1").pack()
Label(sf.scrollable_frame, text="Item 2").pack()
Attributes#
Attribute |
Type |
Description |
|---|---|---|
|
|
The underlying canvas that enables scrolling. |
|
|
The vertical scrollbar. |
|
|
The inner frame — place all content here. |
Note
All child widgets must be placed inside sf.scrollable_frame, not inside sf itself.
QuestionWindow#
QuestionWindow(SubRoot) — A configurable dialog window with a question and one or more
response buttons. Centers on the parent window.
from VIStk.Widgets import QuestionWindow
dlg = QuestionWindow(
question="Save changes before closing?",
answer="yn",
parent=root,
ycommand=save_and_close
)
Constructor#
Parameter |
Type |
Description |
|---|---|---|
|
|
Text to display. A list creates one label per item. |
|
|
A string of character codes defining the buttons (see below). |
|
|
The window to center on. |
|
|
Function called when an affirmative button is clicked. The window is destroyed first. |
|
|
Values for a dropdown ( |
Answer codes#
Code |
Button Text |
Action |
|---|---|---|
|
Yes |
Destroys window, calls |
|
No |
Destroys window. |
|
Return |
Destroys window. |
|
Continue |
Destroys window, calls |
|
Back |
Destroys window. |
|
Close |
Destroys window. |
|
Confirm |
Destroys window, calls |
|
(dropdown) |
|
Examples#
# Yes / No
QuestionWindow("Delete this record?", "yn", root, ycommand=delete_record)
# Confirm / Back
QuestionWindow(["Are you sure?", "This cannot be undone."], "cb", root, ycommand=proceed)
# Multi-line with dropdown
QuestionWindow("Select output format:", "dx", root, droplist=["PDF", "CSV", "JSON"])
WarningWindow#
WarningWindow(QuestionWindow) — A modal warning dialog with a single “Continue” button.
from VIStk.Widgets import WarningWindow
WarningWindow("File not found.", parent=root)
The window is automatically made modal (modalize()), blocking input to the parent until
dismissed. Use for non-recoverable error messages where the user must acknowledge before
continuing.
Tooltip (0.5.0)#
Hover tooltip bound to any widget. Tkinter has no native tooltip.
from VIStk.Widgets import Tooltip
Tooltip(my_button, text="Save the current document")
text may be a string or a zero-arg callable for state-dependent
tooltips (re-evaluated each show). Cleans up its after callback on
widget destroy.
Keyword args: delay_ms=500, wraplength=240, background,
foreground, borderwidth.
CollapsibleFrame (0.5.0)#
Frame whose body is hidden under a header button. Pack children into
cf.body (NOT directly into the frame).
from VIStk.Widgets import CollapsibleFrame
cf = CollapsibleFrame(parent, text="Advanced", expanded=False)
cf.pack(fill="x")
ttk.Entry(cf.body).pack()
cf.expanded_var is a BooleanVar callers can bind to share state
or persist it. Methods: expand(), collapse(), toggle(),
set_expanded(bool), set_text(str).
AutocompleteEntry (0.5.0)#
ttk.Entry with a filtered dropdown Listbox of suggestions.
from VIStk.Widgets import AutocompleteEntry
AutocompleteEntry(parent, values=["Boston", "Chicago", ...]).pack()
values may be an iterable or a callable (text) -> iterable
(use the callable form for dynamic lookups).
Keyword args: max_results=8, case_sensitive=False,
match="prefix" (or "contains").
Keyboard: Up/Down move, Return accepts, Tab accepts the
first match, Escape closes the popup.
DateEntry (0.5.0)#
Date input with format validation and a calendar-picker popup. No third-party dependencies.
from VIStk.Widgets import DateEntry
de = DateEntry(parent, date_format="%Y-%m-%d")
de.pack()
de.get() returns date | None. de.set(d) sets
programmatically. Invalid manual input reverts to the last valid value
on focus-out. Keyword args include initial: date | None,
on_change: callable, entry_width: int.
confirm / confirm_discard (0.5.0)#
Drop-in modal helpers so screens stop reimplementing
tkinter.messagebox.
from VIStk.Widgets import confirm, confirm_discard
if confirm(parent, title="Delete?", message="Really delete?"):
...
choice = confirm_discard(parent, name="Work Order #12345")
if choice == "cancel":
return False # veto on_quit
if choice == "save":
_save()
return True
Both dialogs centre on the parent via WindowGeometry.center_on
(no flicker), are modal/transient, and return plain values
(bool for confirm; "save" | "discard" | "cancel" for
confirm_discard). Closing the window or pressing Escape returns
the negative outcome.