### Install PyTermGUI
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Install the PyTermGUI library using pip.
```bash
pip3 install pytermgui
```
--------------------------------
### Install Prettier Formatter
Source: https://github.com/bczsalba/pytermgui/blob/master/CONTRIBUTING.md
Install Prettier using npm. Node.js and npm are required.
```bash
npx prettier --write .
```
--------------------------------
### Example Hyperlinks in PyTermGUI TIM
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/tags.md
This example demonstrates creating clickable hyperlinks to external websites within the terminal output.
```text
This documentation is hosted as a [~https://ptg.bczsalba.com]subdomain[/~] on my [~https://bczsalba.com]website!
```
--------------------------------
### Widget Auto Syntax Example
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/builtins.md
Demonstrates how the auto syntax can be used with the Container widget to simplify widget creation.
```APIDOC
## Auto Syntax with Container
Some widgets support an `Auto syntax` which can be used by the `auto` function to generate widgets from Python datatypes. This function is called within `Container` and its subclasses to easily create widgets with minimal imports.
### Example Usage
```python
from pytermgui import Container
container = Container(
"[bold accent]This is my example",
"",
"[surface+1 dim italic]It is very cool, you see",
"",
{"My first label": ["Some button"]},
{"My second label": [False]},
"",
("Left side", "Middle", "Right side"),
"",
["Submit button"]
)
```
This is functionally equivalent to:
```python
from pytermgui import Container, Label, Splitter, Button, Checkbox
container = Container(
Label("[bold accent]This is my example"),
Label(""),
Label("[surface+1 dim italic]It is very cool, you see"),
Label(""),
Splitter(
Label("My first label", parent_align=0),
Button("Some button", parent_align=2),
),
Splitter(
Label("My second label"),
Checkbox(),
),
Label(""),
Splitter(Label("Left side"), Label("Middle"), Label("Right side")),
Label(""),
Button("Submit button"),
)
```
```
--------------------------------
### Install Pylint Linter
Source: https://github.com/bczsalba/pytermgui/blob/master/CONTRIBUTING.md
Install Pylint, a Python linter, using pip.
```bash
pip install pylint
```
--------------------------------
### Generate Container with Explicit Widgets
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/builtins.md
This example is functionally identical to the `auto` syntax example but uses explicit widget instantiation for clarity. It requires importing all necessary widget types.
```python
from pytermgui import Container, Label, Splitter, Button, Checkbox
container = Container(
Label("[bold accent]This is my example"),
Label(""),
Label("[surface+1 dim italic]It is very cool, you see"),
Label(""),
Splitter(
Label("My first label", parent_align=0),
Button("Some button", parent_align=2),
),
Splitter(
Label("My second label"),
Checkbox(),
),
Label(""),
Splitter(Label("Left side"), Label("Middle"), Label("Right side")),
Label(""),
Button("Submit button"),
)
```
--------------------------------
### Install Black Formatter
Source: https://github.com/bczsalba/pytermgui/blob/master/CONTRIBUTING.md
Install the Black Python code formatter using pip.
```bash
pip install black
```
--------------------------------
### Integrating Monitor with a Custom Widget
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/custom.md
This example shows how to integrate the `Monitor` class into a custom widget, such as `Weather`. It demonstrates attaching a callback to the monitor for periodic updates and defining the update logic within the widget.
```python
from .monitor import Monitor
from pytermgui import Container
monitor = Monitor().start()
class Weather(Container):
def __init__(self, location: str, timeout: float, **attrs: Any) -> None:
... # Standard init code (see above)
monitor.attach(self._request_and_update, timeout)
def _request_and_update(self) -> None:
self.data = self._request()
self.update_content()
```
--------------------------------
### Handling Keyboard Interrupt Example
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/walkthroughs/inline.md
This example demonstrates how to use a `try-except` block to handle `KeyboardInterrupt` within an infinite loop. Note that this specific example is for illustrative purposes and should not be used in production code due to its potential to create inescapable loops.
```python
from time import time
while True:
try:
print(time())
except KeyboardInterrupt:
pass
return widget
```
--------------------------------
### Generate Container with Auto Syntax
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/builtins.md
This example shows how to create a Container using the `auto` syntax, which simplifies widget creation from Python datatypes.
```python
from pytermgui import Container
container = Container(
"[bold accent]This is my example",
"",
"[surface+1 dim italic]It is very cool, you see",
"",
{"My first label": ["Some button"]},
{"My second label": [False]},
"",
("Left side", "Middle", "Right side"),
"",
["Submit button"]
)
```
--------------------------------
### Install Mypy Type Checker
Source: https://github.com/bczsalba/pytermgui/blob/master/CONTRIBUTING.md
Install Mypy, a static type checker for Python, using pip.
```bash
pip install mypy
```
--------------------------------
### TIM Example Visualization
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/index.md
This is a placeholder for a visual representation of the TIM markup language example, generated using termage-svg. It helps in understanding the rendered output of TIM.
```termage-svg
include=docs/src/tim/index.py title=TIM\ Example height=4
```
--------------------------------
### TIM Styles Example
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/tags.md
This example showcases various text styles supported by TIM, including bold, dim, italic, underline, blink, inverse, invisible, strikethrough, and overline.
```python
from pytermgui import tim
print(tim.parse("[bold italic underline]Styled text[/]"))
# Output: Styled text (with bold, italic, and underline)
```
--------------------------------
### TIM CSS Color Example
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/tags.md
TIM supports CSS color names for easy color application. This example demonstrates using a named color.
```python
from pytermgui import tim
print(tim.parse("[dodger_blue]Text in dodger blue[/]"))
```
--------------------------------
### Build a Contact Form with PyTermGUI and YAML Config
Source: https://github.com/bczsalba/pytermgui/blob/master/README.md
This example shows how to create a contact form using PyTermGUI, leveraging its YAML-based configuration system for styling widgets. It includes input fields for name, address, and phone number, along with a multiline text area for additional notes. The `submit` callback is defined elsewhere.
```python
import pytermgui as ptg
CONFIG = """
config:
InputField:
styles:
prompt: dim italic
cursor: '@72'
Label:
styles:
value: dim bold
Window:
styles:
border: '60'
corner: '60'
Container:
styles:
border: '96'
corner: '96'
"""
with ptg.YamlLoader() as loader:
loader.load(CONFIG)
with ptg.WindowManager() as manager:
window = (
ptg.Window(
"",
ptg.InputField("Balazs", prompt="Name: "),
ptg.InputField("Some street", prompt="Address: "),
ptg.InputField("+11 0 123 456", prompt="Phone number: "),
"",
ptg.Container(
"Additional notes:",
ptg.InputField(
"A whole bunch of\nMeaningful notes\nand stuff", multiline=True
),
box="EMPTY_VERTICAL",
),
"",
["Submit", lambda *_: submit(manager, window)],
width=60,
box="DOUBLE",
)
.set_title("[210 bold]New contact")
.center()
)
manager.add(window)
```
--------------------------------
### Create a Simple Clock with PyTermGUI
Source: https://github.com/bczsalba/pytermgui/blob/master/README.md
This snippet demonstrates how to create a basic clock application using PyTermGUI. It defines a custom TIM macro to display the current time, which is then used within a `Window` widget. Ensure `pytermgui` is installed.
```python3
import time
import pytermgui as ptg
def macro_time(fmt: str) -> str:
return time.strftime(fmt)
ptg.tim.define("!time", macro_time)
with ptg.WindowManager() as manager:
manager.layout.add_slot("Body")
manager.add(
ptg.Window("[bold]The current time is:[/]\n\n[!time 75]%c", box="EMPTY")
)
```
--------------------------------
### Create and Configure Sliders
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Illustrates how to create Slider widgets for selecting numeric values between 0.0 and 1.0. Includes examples of setting initial values, creating locked (read-only) sliders, and applying custom styles.
```python
import pytermgui as ptg
def on_value_change(value):
print(f"Volume: {int(value * 100)}%")
# Basic slider
volume = ptg.Slider(onchange=on_value_change)
volume.value = 0.5 # Set initial value (0.0 to 1.0)
# Locked slider (read-only display)
progress = ptg.Slider(locked=True)
progress.value = 0.75
# Styled slider
ptg.Slider.styles.filled = "green"
ptg.Slider.styles.filled_selected = "bold green"
ptg.Slider.styles.unfilled = "dim"
ptg.Slider.styles.cursor = "bold white"
```
```python
# In a window
with ptg.WindowManager() as manager:
window = ptg.Window(
"[bold]Settings",
"",
ptg.Label("Volume:"),
ptg.Slider(onchange=lambda v: None),
"",
ptg.Label("Brightness:"),
ptg.Slider(onchange=lambda v: None),
width=40,
)
manager.add(window)
```
--------------------------------
### Example Commit Message
Source: https://github.com/bczsalba/pytermgui/blob/master/CONTRIBUTING.md
Use descriptive, imperative commit messages. Capitalize the first letter and do not append a period.
```bash
added a new slider widget # Bad
```
```bash
Add a new slider widget # Good!
```
--------------------------------
### Create Horizontal Layouts with Splitter
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Arrange widgets horizontally using Splitter. Examples include creating a button bar and a two-column form layout.
```python
import pytermgui as ptg
# Create a horizontal button bar
button_bar = ptg.Splitter(
ptg.Button("Save"),
ptg.Button("Cancel"),
ptg.Button("Help"),
)
# Create a two-column form layout
form = ptg.Container(
ptg.Splitter(
ptg.Label("Username:"),
ptg.InputField("admin"),
),
ptg.Splitter(
ptg.Label("Password:"),
ptg.InputField("", prompt=""),
),
box="SINGLE",
)
```
--------------------------------
### Handle Keyboard Input in Custom Widget
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/custom.md
Example of a custom widget handling keyboard input. Always call the parent class's handler first to ensure proper event propagation and compatibility.
```python
class MyWidget(Widget):
def handle_key(self, key: str) -> bool:
if super().handle_key(key):
return
# Do our own handling
```
--------------------------------
### Auto Pseudo-tag Example in PyTermGUI TIM
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/tags.md
The '#auto' pseudo-tag automatically sets a contrasting foreground color if only a background color is specified, adhering to W3C contrast guidelines.
```python
foreground = ...
background = ...
if foreground is None and background is not None:
foreground = get_contrasting_color(background)
```
--------------------------------
### TIM Markup Language Example
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/index.md
This snippet demonstrates the usage of the Terminal Inline Markup (TIM) language within PyTermGUI. It is intended for use in applications that display text and require styled output.
```python
--8<-- "docs/src/tim/index.py"
```
--------------------------------
### Define Custom Macros (Localization)
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/usage.md
Create custom macros for advanced functionality, such as implementing a localization layer. This example defines a `!lang` macro to retrieve localized strings.
```python
from pytermgui import tim
def localize(id):
translations = {
"greeting": "Hello",
"farewell": "Goodbye"
}
return translations.get(id, f"[MISSING: {id}]")
tim.define("lang", localize)
tim.print("[!lang greeting], world!")
tim.print("[!lang farewell]!")
```
--------------------------------
### Position Text in PyTermGUI TIM
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/tags.md
Text can be positioned using coordinates with the syntax '[({x};{y})]'. Coordinates start from the terminal's origin (0,0).
```text
[({x};{y})]
```
--------------------------------
### Save and Restore Cursor for Stable Printing
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/walkthroughs/inline.md
Use save_cursor and restore_cursor to ensure printing always starts at the same terminal location, creating a consistent 'prompt' look. This is useful when dynamically updating widget content.
```diff
from typing import TypeVar
from pytermgui import getch, keys, save_cursor, restore_cursor, Widget
def inline(widget):
while True:
key = getch(interrupts=False)
if key == keys.CTRL_C:
break
widget.handle_key(key)
save_cursor()
for line in widget.get_lines():
print(line)
restore_cursor()
```
```python
from typing import TypeVar
from pytermgui import getch, keys, save_cursor, restore_cursor, Widget
def inline(widget):
while True:
key = getch(interrupts=False)
if key == keys.CTRL_C:
break
widget.handle_key(key)
save_cursor()
for line in widget.get_lines():
print(line)
restore_cursor()
return widget
```
--------------------------------
### Implement Keyboard Input Handling with Keys Singleton
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/custom.md
Demonstrates how to use the `keys` singleton to compare incoming key codes with canonical names for specific actions within a custom widget's keyboard handler.
```python
from pytermgui import Widget, keys
class MyWidget(Widget):
def handle_key(self, key: str) -> bool:
if super().handle_key(key):
return True
if key == keys.CTRL_F:
self.do_something()
return True
return False
```
--------------------------------
### TIM Nesting Example
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/tags.md
When TIM tag groups are nested, only the innermost group is parsed. This example demonstrates how nested tags are handled.
```python
from pytermgui import tim
print(tim.parse("[tag1 [tag2] content]"))
# Output: tag1 content
```
--------------------------------
### Initialize WindowManager and Layout
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Set up the WindowManager for a full-screen application and define a custom layout with slots for header, body, sidebar, and footer.
```python
import pytermgui as ptg
def main():
with ptg.WindowManager() as manager:
# Define a custom layout with header, body, and footer
manager.layout.add_slot("Header", height=1)
manager.layout.add_break()
manager.layout.add_slot("Body")
manager.layout.add_slot("Sidebar", width=0.2)
manager.layout.add_break()
manager.layout.add_slot("Footer", height=1)
# Create and add windows
header = ptg.Window("[bold]My Application", box="EMPTY")
manager.add(header) # Auto-assigns to first slot
main_window = ptg.Window(
"[bold]Welcome!",
"",
ptg.Button("Click Me", lambda btn: manager.alert("Hello!")),
ptg.Button("Quit", lambda btn: manager.stop()),
)
manager.add(main_window, assign="body")
# Create a toast notification
manager.toast("Application started!", duration=500, delay=2000)
if __name__ == "__main__":
main()
```
--------------------------------
### Create and Style Buttons
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Shows how to create simple and styled buttons, including setting click handlers, custom delimiters, and applying styles for different states. Buttons can be activated via mouse click or keyboard.
```python
import pytermgui as ptg
def on_click(button):
print(f"Button '{button.label}' was clicked!")
# Simple button
btn = ptg.Button("Click Me", onclick=on_click)
# Styled button using class-level style configuration
ptg.Button.styles.label = "bold @blue white"
ptg.Button.styles.highlight = "bold @cyan black"
# Button with custom delimiter characters
btn = ptg.Button("Submit")
btn.set_char("delimiter", ["[ ", " ]"])
```
```python
# Using buttons in a container
with ptg.WindowManager() as manager:
window = ptg.Window(
"Choose an action:",
"",
ptg.Button("New File", lambda b: print("Creating file...")),
ptg.Button("Open File", lambda b: print("Opening file...")),
ptg.Button("Exit", lambda b: manager.stop()),
)
manager.add(window)
```
--------------------------------
### Create and Manage Windows
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Create a standard window with input fields and buttons, and a modal confirmation dialog. Windows can be centered and managed by the WindowManager.
```python
import pytermgui as ptg
with ptg.WindowManager() as manager:
# Create a standard window with title
main_window = ptg.Window(
ptg.Label("[bold green]Settings"),
"",
ptg.InputField("Username", prompt="User: "),
ptg.InputField("", prompt="Password: "),
"",
ptg.Button("Save", lambda btn: btn.parent.close()),
box="DOUBLE",
width=50,
).set_title("User Settings").center()
manager.add(main_window)
# Create a modal confirmation dialog
def show_confirm():
modal = ptg.Window(
"[bold]Are you sure?",
"",
ptg.Splitter(
ptg.Button("Yes", lambda btn: manager.stop()),
ptg.Button("No", lambda btn: modal.close()),
),
is_modal=True, # Blocks interaction with other windows
).center()
manager.add(modal)
```
--------------------------------
### Inspect Size Policy Helpers
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/attrs.md
Demonstrates the inspection of helper properties for setting widget width policies.
```python
from pytermgui import inspect, Widget
print(inspect(Widget.static_width.fget, show_header=False))
print("\n")
print(inspect(Widget.relative_width.fget, show_header=False))
```
--------------------------------
### TIM Escaping Example
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/tags.md
Tag groups in TIM can be escaped using backslashes to prevent them from being parsed. Note that the backslash is removed during the first parsing.
```python
from pytermgui import tim
print(tim.parse(r"[tag1 \\ [tag2] content]"))
# Output: [tag1 [tag2] content]
```
--------------------------------
### Create Hyperlinks in PyTermGUI TIM
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/tags.md
Hyperlinks are created using the syntax '[~{protocol}://{uri}]'. The protocol can be http, https, or file, and uri is a standard URI.
```text
[~{protocol}://{uri}]
```
--------------------------------
### Create Input Fields
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Demonstrates the creation of single-line and multi-line input fields with prompts and custom styling. InputFields support advanced text navigation and mouse cursor positioning.
```python
import pytermgui as ptg
# Single-line input with prompt
name_field = ptg.InputField("", prompt="Name: ")
# Multi-line text area
notes_field = ptg.InputField(
"Enter your notes here...",
prompt="Notes: ",
multiline=True,
)
# Input with custom styling
ptg.InputField.styles.prompt = "bold yellow"
ptg.InputField.styles.cursor = "@blue white"
```
```python
# Using InputField in a form
with ptg.WindowManager() as manager:
def submit_form(btn):
# Access input values
name = name_input.value
email = email_input.value
print(f"Submitted: {name}, {email}")
manager.stop()
name_input = ptg.InputField("", prompt="Name: ")
email_input = ptg.InputField("", prompt="Email: ")
window = ptg.Window(
"[bold]Contact Form",
"",
name_input,
email_input,
"",
ptg.Button("Submit", submit_form),
)
manager.add(window)
```
--------------------------------
### Clear Terminal Mode in PyTermGUI TIM
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/tags.md
To clear a specific terminal mode, prefix the mode name with '/'. For example, use '/italic' to clear italicization.
```text
/{mode}
```
```text
/italic
```
--------------------------------
### Basic Inline Widget Implementation
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/walkthroughs/inline.md
This function allows a widget to process keyboard inputs and render its lines sequentially. It requires importing `getch` and `Widget` from `pytermgui`. The loop continues indefinitely until interrupted.
```python
from pytermgui import getch, Widget
def inline(widget):
while True:
key = getch()
widget.handle_key(key)
for line in widget.get_lines():
print(line)
return widget
```
--------------------------------
### Apply Auto Contrast Markup
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/styling.md
Demonstrates how to use the '#auto' markup pseudo-tag to ensure sufficient contrast ratios for text, especially when using custom colors. This is particularly useful for dynamically generated styles.
```python
from pytermgui import tim
tim.alias_multiple(**{"@my-surface1": "@white", "@my-surface2": "@black"})
tim.print("[@my-surface1 #auto] Black on white [@my-surface2 #auto] White on black ")
```
--------------------------------
### Inspect Function Signature and Docstring
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/inspect.md
Use the `inspect` function to get information about a Python object, including its signature and docstring. This is useful for understanding how to use functions and methods.
```python
from pytermgui import inspect
def my_function(a: int, b: str = "hello") -> bool:
"""This is a sample function."""
return True
print(inspect(my_function))
```
--------------------------------
### Build Forms with Container
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Construct a registration form using Container, stacking widgets vertically. Demonstrates using Container with labels, input fields, toggles, and buttons, and also shows the fluent API with the '+' operator.
```python
import pytermgui as ptg
# Build a form using Container
form = ptg.Container(
ptg.Label("[bold 141]Registration Form"),
"",
ptg.InputField("", prompt="Name: "),
ptg.InputField("", prompt="Email: "),
"",
ptg.Container(
ptg.Label("Select your role:"),
ptg.Toggle(("Developer", "Designer"), lambda t: print(f"Selected: {t.value}")),
box="ROUNDED",
),
"",
ptg.Button("Submit"),
box="DOUBLE",
width=50,
)
# Using the fluent API with + operator
form = (
ptg.Container(id="myform")
+ "[bold]Title"
+ ""
+ {"Label": "Value"} # Creates a Splitter with left-right alignment
+ ["Submit", lambda btn: print("Submitted")] # Creates a Button
)
form.center().print()
```
--------------------------------
### Create Toggles and Checkboxes
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Explains how to create Toggle widgets for switching between options and Checkbox widgets for boolean selections. Both support click and keyboard activation, and can be used with shorthand syntax in containers.
```python
import pytermgui as ptg
# Toggle between two options
theme_toggle = ptg.Toggle(
("Light Mode", "Dark Mode"),
lambda toggle: print(f"Selected: {toggle.value}")
)
# Checkbox for boolean selection
def on_check(checkbox):
status = "enabled" if checkbox.checked else "disabled"
print(f"Notifications {status}")
# Using shorthand syntax in containers
form = ptg.Container(
"[bold]Preferences",
"",
ptg.Toggle(("Off", "On")),
"",
# Shorthand: [bool, callback] creates Checkbox
[True, lambda cb: print(f"Checked: {cb.checked}")],
"",
# Shorthand: [(label1, label2), callback] creates Toggle
[("Option A", "Option B"), lambda t: print(t.value)],
)
```
--------------------------------
### Export Terminal Output as SVG without Chrome
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/exports.md
Specify `chrome=False` when exporting to SVG to get an image containing only the code's output, without the window's title bar. This provides a cleaner rectangular image.
```termage-svg
```termage-svg chrome=false include=docs/src/exports1.py height=5
```
```
--------------------------------
### Implement Key Bindings for Widgets
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Add keyboard shortcuts to widgets or the WindowManager for custom actions. Bindings can be global (WindowManager level) or local (widget level). Use predefined key constants for common keys.
```python
import pytermgui as ptg
with ptg.WindowManager() as manager:
window = ptg.Window(
"[bold]Press keys to test bindings",
"",
ptg.Label("CTRL+Q: Quit"),
ptg.Label("CTRL+S: Save"),
ptg.Label("CTRL+N: New window"),
)
# Bind at WindowManager level (global)
manager.bind(ptg.keys.CTRL_Q, lambda *_: manager.stop(), "Quit application")
manager.bind(ptg.keys.CTRL_S, lambda *_: print("Saving..."), "Save")
# Bind at window level
def create_new_window(*_):
new_win = ptg.Window("New Window", ptg.Button("Close", lambda b: new_win.close()))
manager.add(new_win.center())
window.bind(ptg.keys.CTRL_N, create_new_window, "Create new window")
# Common key constants
# ptg.keys.ENTER, ptg.keys.ESCAPE, ptg.keys.TAB
# ptg.keys.UP, ptg.keys.DOWN, ptg.keys.LEFT, ptg.keys.RIGHT
# ptg.keys.CTRL_A through ptg.keys.CTRL_Z
# ptg.keys.F1 through ptg.keys.F12
# ptg.keys.BACKSPACE, ptg.keys.DELETE
manager.add(window)
```
--------------------------------
### Configure Widget Styles and Theming
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Customize the appearance of widgets globally or for specific instances using styles and TIM aliases. Define a color palette and apply styles to widget classes like Button, Window, and Label. Instance-specific styles can override global settings.
```python
import pytermgui as ptg
# Define color palette
PALETTE = {
"primary": "#3498db",
"secondary": "#2ecc71",
"background": "#1a1a2e",
"surface": "#16213e",
"text": "#eaeaea",
}
# Create TIM aliases for the palette
for name, color in PALETTE.items():
ptg.tim.alias(name, color)
ptg.tim.alias(f"@{name}", f"@{color}")
# Configure widget styles globally
ptg.Button.styles.label = "@primary text bold"
ptg.Button.styles.highlight = "@secondary text bold"
ptg.Window.styles.border = "primary"
ptg.Window.styles.corner = "primary"
ptg.Window.styles.fill = "@background"
ptg.Container.styles.border = "surface"
ptg.Container.styles.corner = "surface"
ptg.Container.styles.fill = "@surface"
ptg.Label.styles.value = "text"
ptg.InputField.styles.prompt = "text dim"
ptg.InputField.styles.cursor = "@primary text"
# Set focus styles for windows
ptg.Window.set_focus_styles(
focused=("primary", "primary"),
blurred=("surface dim", "surface dim"),
)
```
```python
# Configure specific instance styles
with ptg.WindowManager() as manager:
window = ptg.Window(
ptg.Label("[bold primary]Themed Application"),
"",
ptg.Button("Primary Action"),
ptg.Button("Secondary Action"),
)
# Override instance-specific styles
window.styles.border = "secondary"
window.styles.corner = "secondary"
manager.add(window)
```
--------------------------------
### Apply Box Styles to Widgets
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Demonstrates how to apply built-in and custom box styles to specific widget instances or set default styles for widget classes. Use built-in styles like 'DOUBLE' or 'ROUNDED' by name, or define a custom box using a list of characters.
```python
import pytermgui as ptg
# Built-in box types
# SINGLE, DOUBLE, ROUNDED, HEAVY, EMPTY, EMPTY_VERTICAL
# Apply box to a specific widget instance
window = ptg.Window("Content", box="DOUBLE")
container = ptg.Container("Nested", box="ROUNDED")
# Set default box for all windows
ptg.boxes.DOUBLE.set_chars_of(ptg.Window)
ptg.boxes.ROUNDED.set_chars_of(ptg.Container)
# Define custom box
custom_box = ptg.boxes.Box([
"╔═ ═╗",
"║ x ║",
"╚═ ═╝",
])
window = ptg.Window("Custom border", box=custom_box)
```
```python
# Available built-in boxes
with ptg.WindowManager() as manager:
for box_name in ["SINGLE", "DOUBLE", "ROUNDED", "HEAVY"]:
window = ptg.Window(
f"Box: {box_name}",
ptg.Label("Sample content"),
box=box_name,
width=30,
)
manager.add(window, assign=False)
```
--------------------------------
### Create Nested Splitter Layout
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Demonstrates how to create a complex layout using nested Splitter widgets within a Container. This allows for dividing the terminal screen into multiple resizable panes.
```python
layout = ptg.Container(
ptg.Splitter(
ptg.Container("Left Panel", box="ROUNDED"),
ptg.Container("Center Panel", box="ROUNDED"),
ptg.Container("Right Panel", box="ROUNDED"),
),
width=80,
)
```
--------------------------------
### Container Box Presets
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/attrs.md
Sets the border and corner characters for a container using predefined box styles. Defaults to SINGLE for Container and DOUBLE for Window.
```python
from pytermgui import Box
# Example usage (not in source, but illustrative)
# container.set_attribute("box", Box.SQUARE)
# container.set_attribute("box", "ROUNDED")
```
--------------------------------
### Run Pylint
Source: https://github.com/bczsalba/pytermgui/blob/master/CONTRIBUTING.md
Execute Pylint on the pytermgui package to check for code standards. A score below 10.0 will prevent merging.
```bash
pylint pytermgui
```
--------------------------------
### Window Widget
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/builtins.md
Documentation for the Window widget, an extended Container used within the window manager context, with focus-aware styling.
```APIDOC
## Window Widget
### Description
An extended version of `Container`, used in the `window_manager` context.
### Auto Syntax
N/A
### Chars
- See `Container`.
### Styles
Same as `Container`, but expanded with:
- `border_focused`: Analogous to `border`, but only applied when the window is focused.
Default: `surface`.
- `corner_focused`: Analogous to `corner`, but only applied when the window is focused.
Default: `surface`.
- `border_blurred`: Analogous to `border`, but only applied when the window is **NOT** focused.
Default: `surface-2`.
- `corner_blurred`: Analogous to `corner`, but only applied when the window is **NOT** focused.
Default: `surface-2`.
```
--------------------------------
### HTML Equivalent of Hyperlinks
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/tags.md
This shows the HTML structure that the PyTermGUI TIM hyperlink markup is equivalent to.
```html
This documentation is hosted as a subdomain on my website!
```
--------------------------------
### Widget Size Policy Configuration
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/attrs.md
Defines how a widget adjusts its width. FILL uses parent width, STATIC maintains a fixed width, and RELATIVE uses a percentage. Ensure sufficient parent width when using STATIC.
```python
from pytermgui import SizePolicy
# Example usage (not in source, but illustrative)
# widget.set_attribute("width_policy", SizePolicy.STATIC)
# widget.set_attribute("width", 50)
```
--------------------------------
### Run Mypy
Source: https://github.com/bczsalba/pytermgui/blob/master/CONTRIBUTING.md
Execute Mypy on the pytermgui package to check for type errors. Code must pass Mypy with no errors to be merged.
```bash
mypy pytermgui
```
--------------------------------
### Container Widget
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/builtins.md
Documentation for the Container widget, used for stacking other widgets vertically and optionally displaying a border.
```APIDOC
## Container Widget
### Description
A widget to display other widgets, stacked vertically. It may display a box around said widgets as well, using the `border` and `corner` characters.
### Auto Syntax
N/A
### Chars
- `border`: A `list[str]` in the order `left, top, right, bottom` that makes up the borders of the outer box.
- `corner`: A `list[str]` in the order `top_left, top_right, bottom_right, bottom_left` that makes up the corners of the outer box.
### Styles
- `border`: Applies to all border characters of the outer box.
Default: `surface`.
- `corner`: Applies to all corner characters of the outer box.
Default: `surface`.
- `fill`: Applies to the filler characters used for padding.
Default: `background`.
```
--------------------------------
### Clear Foreground/Background Color in PyTermGUI TIM
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/tags.md
Use '/fg' to clear foreground colors and '/bg' to clear background colors.
```text
/fg
```
```text
/bg
```
--------------------------------
### Create Custom Widget Styles with Callables
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/styling.md
For fine-grained control over widget styles, use custom callables that accept `depth` and `item` as arguments and return ANSI-coded text. This method provides more power but is more verbose.
```python
def my_style(depth: int, item: str) -> str:
# ... implementation ...
```
--------------------------------
### Implement Semantic Mouse Handlers
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/custom.md
Define methods like `on_left_click` to handle specific mouse events. These are called before the generic `handle_mouse` if defined. The most specific handler is executed.
```python
from pytermgui import MouseEvent, Widget
class MyWidget(Widget):
label: str = "No action"
def get_lines(self) -> list[str]:
return [self.label]
def on_left_click(self, event: MouseEvent) -> bool:
self.label = "Left click"
return True
def on_click(self, event: MouseEvent) -> bool:
self.label = "Generic click"
return True
def handle_mouse(self, event: MouseEvent) -> bool:
# Make sure we call the super handler
if super().handle_mouse(event):
return True
self.label = "No action"
return True
```
--------------------------------
### Define Widgets with YAML Configuration
Source: https://context7.com/bczsalba/pytermgui/llms.txt
Utilize YamlLoader to define widgets, styles, and layouts using YAML files. This separates UI structure from application logic, allowing for easier management and modification of the user interface.
```yaml
config:
InputField:
styles:
prompt: dim italic
cursor: '@72'
Label:
styles:
value: dim bold
Window:
styles:
border: '60'
corner: '60'
box: DOUBLE
Container:
styles:
border: '96'
corner: '96'
markup:
title-style: 'bold 210'
button-style: '@60 bold'
widgets:
LoginForm:
type: Window
width: 50
widgets:
- Label:
value: '[title-style]Login'
- Label: {}
- InputField:
prompt: 'Username: '
- InputField:
prompt: 'Password: '
- Label: {}
- Button:
label: '[button-style]Submit'
```
```python
import pytermgui as ptg
# Define configuration as a YAML string
CONFIG = """
config:
InputField:
styles:
prompt: dim italic
cursor: '@72'
Label:
styles:
value: dim bold
Window:
styles:
border: '60'
corner: '60'
box: DOUBLE
Container:
styles:
border: '96'
corner: '96'
markup:
title-style: 'bold 210'
button-style: '@60 bold'
widgets:
LoginForm:
type: Window
width: 50
widgets:
- Label:
value: '[title-style]Login'
- Label: {}
- InputField:
prompt: 'Username: '
- InputField:
prompt: 'Password: '
- Label: {}
- Button:
label: '[button-style]Submit'
"""
with ptg.YamlLoader() as loader:
namespace = loader.load(CONFIG)
with ptg.WindowManager() as manager:
# Access widget by name from namespace
login_window = namespace.LoginForm.center()
manager.add(login_window)
```
--------------------------------
### Window Title Configuration
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/attrs.md
Sets the text displayed in the top-left corner of a window's border. Markup is supported if the window's corner style parses TIM.
```python
# Example usage (not in source, but illustrative)
# window.set_attribute("title", "My Window")
# window.set_attribute("title", "[bold]Important[/bold] Info")
```
--------------------------------
### Load YAML Stylesheet
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/future.md
Loads a PyTermGUI YAML stylesheet file. Set auto_reload to True to automatically reload the stylesheet when the file changes.
```yaml
aliases:
main-background: '@surface-1'
main-foreground: 'surface+1'
config:
*:
background: 'main-background'
Window is_modal?:
borders: 'DOUBLE'
styles.border__corner: 'error'
Button .confirm:
styles.normal:
background: '@success-2'
foreground: 'success'
styles.hover:
background: '@success'
foreground: 'success+1'
styles.active:
background: '@success+1'
foreground: 'success+2'
```
```python
from pytermgui import Stylesheet
styles = Stylesheet.load("styles.ptg", auto_reload=True)
```
--------------------------------
### Splitter Widget
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/builtins.md
Documentation for the Splitter widget, used for stacking widgets horizontally and separating them with a defined character.
```APIDOC
## Splitter Widget
### Description
Similar to Container, but displays widgets stacked horizontally instead. Each widget is separated by the `separator` character set.
### Auto Syntax
- `(widget1, widget2, ...)`
- `{widget_aligned_left: widget_aligned_right}`
### Chars
- `separator`: The `str` used to join the contained widgets.
### Styles
- `separator`: Applies to the `separator` character.
Default: `surface`.
```
--------------------------------
### Format Code with Black
Source: https://github.com/bczsalba/pytermgui/blob/master/CONTRIBUTING.md
Run the Black formatter to format all Python files in the current directory and its subdirectories. This command will overwrite files.
```bash
black .
```
--------------------------------
### Define Custom Widget Styles with TIM Shorthands
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/styling.md
Use TIM string shorthands to define custom widget styles. These shorthands are expanded automatically into full markup strings. The `item` template key must be present in the final style string.
```python
surface+2 italic dim
```
```python
[!gradient(210) bold]{item}
```
--------------------------------
### Style Terminal Text with TIM Markup
Source: https://context7.com/bczsalba/pytermgui/llms.txt
PyTermGUI's TIM (Terminal Inline Markup) language allows for styling text with colors, styles, macros, aliases, and hyperlinks directly within strings. Aliases and macros can be defined for reusable styles and dynamic content.
```python
import pytermgui as ptg
import time
# Basic markup - colors and styles
ptg.tim.print("[bold]Bold text[/bold]")
ptg.tim.print("[italic 141]Colored italic text[/]")
ptg.tim.print("[bold @blue white]White on blue background[/]")
ptg.tim.print("[underline strikethrough]Multiple styles[/]")
# CSS color names
ptg.tim.print("[coral]CSS color support[/coral]")
# RGB and HEX colors
ptg.tim.print("[#FF5733]HEX color[/]")
ptg.tim.print("[@rgb(50,100,150)]RGB background[/]")
# Create aliases for reusable styles
ptg.tim.alias("error", "bold red")
ptg.tim.alias("success", "bold green")
ptg.tim.alias("warning", "bold yellow @black")
ptg.tim.print("[error]Error message[/error]")
ptg.tim.print("[success]Success message[/success]")
ptg.tim.print("[warning]Warning message[/warning]")
# Define macros for dynamic content
def show_time(fmt: str) -> str:
return time.strftime(fmt)
ptg.tim.define("!time", show_time)
# Use macro in markup (refreshes on each parse)
ptg.tim.print("Current time: [bold !time '%H:%M:%S']")
# Hyperlinks
ptg.tim.print("[link=https://github.com]Click here[/link]")
# Auto-contrasting text with #auto
ptg.tim.print("[@red #auto]Auto-contrast on red[/]")
ptg.tim.print("[@yellow #auto]Auto-contrast on yellow[/]")
```
--------------------------------
### Inline Widget Display and Keyboard Handling
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/walkthroughs/inline.md
This function displays a widget inline, handles keyboard input for widget interaction, and refreshes the display. It requires PyTermGUI imports for terminal operations, cursor management, and key handling.
```python
from typing import TypeVar
from pytermgui import (
getch,
keys,
save_cursor,
restore_cursor,
Widget,
clear,
get_terminal,
)
def inline(widget):
# Make sure we use the global terminal
terminal = get_terminal()
def _print_widget():
save_cursor()
for line in widget.get_lines():
print(line)
restore_cursor()
def _clear_widget():
save_cursor()
for _ in range(widget.height):
clear("line")
terminal.write("\n")
restore_cursor()
terminal.flush()
_print_widget()
while True:
key = getch(interrupts=False)
if key == keys.CTRL_C:
break
widget.handle_key(key)
_clear_widget()
_print_widget()
_clear_widget()
return widget
```
--------------------------------
### Integrating Mouse Support with Inline Widgets
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/walkthroughs/inline.md
Enhances inline widget handling by adding mouse event support. It uses the `mouse_handler` context manager to translate raw input into `MouseEvent` objects and passes them to the widget. Ensure `report_cursor()` is called to set the widget's position.
```python
from typing import TypeVar
from pytermgui import (
getch,
keys,
save_cursor,
restore_cursor,
report_cursor,
Widget,
clear,
get_terminal,
mouse_handler,
)
def inline(widget):
# Make sure we use the global terminal
terminal = get_terminal()
widget.pos = report_cursor()
def _print_widget():
save_cursor()
for line in widget.get_lines():
print(line)
restore_cursor()
def _clear_widget():
save_cursor()
for _ in range(widget.height):
clear("line")
terminal.write("\n")
restore_cursor()
terminal.flush()
_print_widget()
with mouse_handler(["all"], "decimal_xterm") as translate:
while True:
key = getch(interrupts=False)
if key == keys.CTRL_C:
break
if not widget.handle_key(key):
events = translate(key)
# Don't try iterating when there are no events
if events is None:
continue
for event in events:
if event is None:
continue
widget.handle_mouse(event)
_clear_widget()
_print_widget()
_clear_widget()
return widget
```
--------------------------------
### Handle Specific Mouse Actions
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/custom.md
Check the `event.action` attribute to respond to specific mouse interactions like left clicks. Ensure to call the superclass handler first.
```python
from pytermgui import Widget, MouseEvent, MouseAction
class MyWidget(Widget):
def handle_mouse(self, event: MouseEvent) -> bool:
if super().handle_mouse(event):
return True
if event.action == MouseAction.LEFT_CLICK:
self.do_something()
```
--------------------------------
### MarkupLanguage.print
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/usage.md
A helper function to print parsed TIM text directly to the terminal.
```APIDOC
## MarkupLanguage.print
### Description
Prints TIM formatted text directly to the terminal, simplifying the process of displaying parsed content. It accepts the same positional and keyword arguments as the built-in `print` function.
### Method
`print`
### Endpoint
N/A (Method of MarkupLanguage instance)
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
- ***args** (any) - Positional arguments to be passed to the underlying print function.
- ****kwargs** (any) - Keyword arguments to be passed to the underlying print function.
### Request Example
```json
{
"args": ["This is [color=blue]blue[/color] text."],
"kwargs": {"end": "\n"}
}
```
### Response
#### Success Response (200)
Prints the formatted text to standard output.
#### Response Example
(No JSON response, output is printed to console)
```
--------------------------------
### Define Macro with Arguments in PyTermGUI TIM
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/tim/tags.md
Macros with arguments are defined using the syntax '[!{name}({arg1}:{arg2})]'. Arguments are separated by colons.
```text
[!{name}({arg1}:{arg2})]
```
--------------------------------
### Monitor Implementation for Periodic Updates
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/custom.md
This class provides a mechanism to periodically call registered callbacks. It uses a single master thread to manage multiple listeners, ensuring efficient background updates without overusing threads.
```python
from __future__ import annotations
from dataclasses import dataclass, field
from threading import Thread
from time import sleep, time
from typing import Callable
@dataclass
class Listener:
callback: Callable[[], None]
period: float
time_till_next: float
@dataclass
class Monitor:
update_frequency: float = 0.5
listeners: list[Listener] = field(default_factory=list)
def attach(self, callback: Callable[[], None], *, period: float) -> Listener:
listener = Listener(callback, period, period)
self.listeners.append(listener)
return listener
def start(self) -> Monitor:
def _monitor() -> None:
previous = time()
while True:
elapsed = time() - previous
for listener in self.listeners:
listener.time_till_next -= elapsed
if listener.time_till_next <= 0.0:
listener.callback()
listener.time_till_next = listener.period
previous = time()
sleep(self.update_frequency)
Thread(target=_monitor).start()
return self
```
--------------------------------
### Label Widget
Source: https://github.com/bczsalba/pytermgui/blob/master/docs/widgets/builtins.md
Documentation for the Label widget, used for displaying text with support for styling and line breaking.
```APIDOC
## Label Widget
### Description
A simple widget meant to display text. Supports line breaking and styling using both markup and simple callables.
### Auto Syntax
`"label_value"`
### Chars
N/A
### Styles
- `value`: Applies to the text within the label.
Default: No styling.
```