Cython-based Python bindings for dear imgui - a bloat-free immediate mode graphical user interface library
—
Tab bar system for organizing content into multiple views with support for reordering, closing, and dynamic tab management. The tab system provides an intuitive way to manage multiple panels or documents within a single window interface.
Core functions for creating and managing tab bar containers.
def begin_tab_bar(identifier: str, flags: int = 0) -> bool:
"""Begin tab bar. Returns True if tab bar is visible."""
def end_tab_bar() -> None:
"""End tab bar."""Functions for creating individual tabs within a tab bar.
def begin_tab_item(label: str, opened: bool = None, flags: int = 0) -> tuple[bool, bool]:
"""Begin tab item. Returns (is_selected, is_open)."""
def end_tab_item() -> None:
"""End tab item."""
def tab_item_button(label: str, flags: int = 0) -> bool:
"""Create a tab button (not selectable). Returns True when clicked."""
def set_tab_item_closed(tab_or_docked_window_label: str) -> None:
"""Close tab programmatically."""Constants for controlling tab bar behavior and appearance.
TAB_BAR_NONE: int
TAB_BAR_REORDERABLE: int # Allow dragging tabs to reorder
TAB_BAR_AUTO_SELECT_NEW_TABS: int # Automatically select new tabs
TAB_BAR_TAB_LIST_POPUP_BUTTON: int # Disable tab list popup button
TAB_BAR_NO_CLOSE_WITH_MIDDLE_MOUSE_BUTTON: int # Disable middle mouse close
TAB_BAR_NO_TAB_LIST_SCROLLING_BUTTONS: int # Disable scrolling buttons
TAB_BAR_NO_TOOLTIP: int # Disable tooltips on tabs
TAB_BAR_FITTING_POLICY_RESIZE_DOWN: int # Resize tabs when they don't fit
TAB_BAR_FITTING_POLICY_SCROLL: int # Add scroll buttons when tabs don't fit
TAB_BAR_FITTING_POLICY_MASK: int
TAB_BAR_FITTING_POLICY_DEFAULT: int # Default fitting policyConstants for controlling individual tab behavior.
TAB_ITEM_NONE: int
TAB_ITEM_UNSAVED_DOCUMENT: int # Append '*' to title for unsaved
TAB_ITEM_SET_SELECTED: int # Make tab selected when created
TAB_ITEM_NO_CLOSE_WITH_MIDDLE_MOUSE_BUTTON: int # Disable middle mouse close
TAB_ITEM_NO_PUSH_ID: int # Don't call PushID/PopID
TAB_ITEM_NO_TOOLTIP: int # Disable tooltip for this tab
TAB_ITEM_NO_REORDER: int # Disable reordering this tab
TAB_ITEM_LEADING: int # Enforce tab position to left
TAB_ITEM_TRAILING: int # Enforce tab position to rightimport imgui
# Simple tab bar with multiple tabs
if imgui.begin_tab_bar("MyTabBar"):
# Tab 1
selected, opened = imgui.begin_tab_item("Tab 1")
if selected:
imgui.text("Content of Tab 1")
imgui.button("Button in Tab 1")
imgui.end_tab_item()
# Tab 2
selected, opened = imgui.begin_tab_item("Tab 2")
if selected:
imgui.text("Content of Tab 2")
imgui.slider_float("Slider", 0.5, 0.0, 1.0)
imgui.end_tab_item()
# Tab 3
selected, opened = imgui.begin_tab_item("Tab 3")
if selected:
imgui.text("Content of Tab 3")
imgui.input_text("Input", "", 256)
imgui.end_tab_item()
imgui.end_tab_bar()# Tab bar with closeable tabs
tab_states = {
"Document 1": True,
"Document 2": True,
"Document 3": True,
}
if imgui.begin_tab_bar("DocumentTabs"):
# Create tabs for each open document
tabs_to_close = []
for tab_name, is_open in tab_states.items():
if is_open:
selected, still_open = imgui.begin_tab_item(tab_name, True)
if selected:
imgui.text(f"Content of {tab_name}")
imgui.text("This tab can be closed with the X button")
if imgui.button(f"Save {tab_name}"):
print(f"Saving {tab_name}")
imgui.end_tab_item()
# Track which tabs were closed
if not still_open:
tabs_to_close.append(tab_name)
# Remove closed tabs
for tab_name in tabs_to_close:
tab_states[tab_name] = False
imgui.end_tab_bar()
# Button to reopen closed tabs
if imgui.button("Reopen All Tabs"):
for tab_name in tab_states:
tab_states[tab_name] = True# Tab bar with reorderable tabs
if imgui.begin_tab_bar("ReorderableTabs", imgui.TAB_BAR_REORDERABLE):
tab_names = ["Alpha", "Beta", "Gamma", "Delta"]
for tab_name in tab_names:
selected, opened = imgui.begin_tab_item(tab_name)
if selected:
imgui.text(f"Content of {tab_name}")
imgui.text("Drag tabs to reorder them")
imgui.end_tab_item()
imgui.end_tab_bar()# Document tabs with unsaved indicators
documents = {
"main.py": {"modified": False, "content": "print('Hello World')"},
"utils.py": {"modified": True, "content": "def helper(): pass"},
"config.json": {"modified": True, "content": '{"key": "value"}'},
}
if imgui.begin_tab_bar("DocumentEditor"):
for doc_name, doc_info in documents.items():
# Use unsaved document flag if modified
flags = imgui.TAB_ITEM_UNSAVED_DOCUMENT if doc_info["modified"] else imgui.TAB_ITEM_NONE
selected, opened = imgui.begin_tab_item(doc_name, True, flags)
if selected:
imgui.text(f"Editing: {doc_name}")
# Simple text editor
changed, new_content = imgui.input_text_multiline(
"##editor", doc_info["content"], 1024, -1, 200
)
if changed:
doc_info["content"] = new_content
doc_info["modified"] = True
# Save button
if imgui.button("Save"):
doc_info["modified"] = False
print(f"Saved {doc_name}")
imgui.end_tab_item()
# Remove document if tab was closed
if not opened:
del documents[doc_name]
break # Break to avoid modifying dict during iteration
imgui.end_tab_bar()# Tab bar with leading and trailing buttons
if imgui.begin_tab_bar("TabsWithButtons"):
# Leading button (always on the left)
if imgui.tab_item_button("+", imgui.TAB_ITEM_LEADING):
print("Add new tab")
# Regular tabs
tab_names = ["Home", "Settings", "About"]
for tab_name in tab_names:
selected, opened = imgui.begin_tab_item(tab_name)
if selected:
imgui.text(f"Content of {tab_name} tab")
imgui.end_tab_item()
# Trailing button (always on the right)
if imgui.tab_item_button("?", imgui.TAB_ITEM_TRAILING):
print("Show help")
imgui.end_tab_bar()# Dynamic tab system
import time
tab_counter = 1
active_tabs = {}
if imgui.begin_tab_bar("DynamicTabs", imgui.TAB_BAR_AUTO_SELECT_NEW_TABS):
# Add new tab button
if imgui.tab_item_button("+"):
tab_id = f"Tab {tab_counter}"
active_tabs[tab_id] = {
"created_time": time.time(),
"content": f"Dynamic content for {tab_id}"
}
tab_counter += 1
# Display existing tabs
tabs_to_remove = []
for tab_id, tab_data in active_tabs.items():
selected, opened = imgui.begin_tab_item(tab_id, True)
if selected:
imgui.text(f"Tab ID: {tab_id}")
imgui.text(f"Created: {time.ctime(tab_data['created_time'])}")
imgui.text(tab_data["content"])
if imgui.button(f"Close {tab_id}"):
tabs_to_remove.append(tab_id)
imgui.end_tab_item()
if not opened:
tabs_to_remove.append(tab_id)
# Remove closed tabs
for tab_id in tabs_to_remove:
del active_tabs[tab_id]
imgui.end_tab_bar()# Tab bar that handles many tabs
many_tabs = [f"Tab {i+1}" for i in range(20)]
# Tab bar with scrolling when tabs don't fit
if imgui.begin_tab_bar("ScrollingTabs", imgui.TAB_BAR_FITTING_POLICY_SCROLL):
for tab_name in many_tabs:
selected, opened = imgui.begin_tab_item(tab_name)
if selected:
imgui.text(f"Content of {tab_name}")
imgui.text("There are many tabs - scroll to see them all")
imgui.end_tab_item()
imgui.end_tab_bar()
imgui.separator()
# Tab bar with resizing when tabs don't fit
if imgui.begin_tab_bar("ResizingTabs", imgui.TAB_BAR_FITTING_POLICY_RESIZE_DOWN):
for tab_name in many_tabs[:10]: # Show fewer tabs for resize example
selected, opened = imgui.begin_tab_item(tab_name)
if selected:
imgui.text(f"Content of {tab_name}")
imgui.text("Tabs resize to fit available space")
imgui.end_tab_item()
imgui.end_tab_bar()# Programmatic tab selection and closing
selected_tab = "Tab 1" # This would be maintained in your application state
if imgui.begin_tab_bar("ProgrammaticTabs"):
tab_names = ["Tab 1", "Tab 2", "Tab 3", "Tab 4"]
for tab_name in tab_names:
# Set selected flag for the chosen tab
flags = imgui.TAB_ITEM_SET_SELECTED if tab_name == selected_tab else imgui.TAB_ITEM_NONE
is_selected, opened = imgui.begin_tab_item(tab_name, True, flags)
if is_selected:
imgui.text(f"Content of {tab_name}")
# Buttons to programmatically switch tabs
for other_tab in tab_names:
if other_tab != tab_name:
if imgui.button(f"Go to {other_tab}"):
selected_tab = other_tab
imgui.end_tab_item()
imgui.end_tab_bar()
# Buttons to close tabs programmatically
imgui.text("Close tabs programmatically:")
for tab_name in tab_names:
if imgui.small_button(f"Close {tab_name}"):
imgui.set_tab_item_closed(tab_name)
imgui.same_line()Install with Tessl CLI
npx tessl i tessl/pypi-imgui