pytermgui.widgets
The widget system.
Basic concept
Everything starts with the Widget
class. It represents a single part
of the overarching system. Simple widgets like Label
simply implement
a get_lines
method, in which they can come up with what to display as.
The more complex type widget is something like Container
. This widget holds
other widgets within itself, and uses some fancy logic to display them
in a neat and organized way.
Magic methods
Most widgets support a selection of magic methods, also known as dunders.
For example, all Container
children are iterable by default, and allow
adding elements using the +=
operator. You can also index into them, if
that floats your boat.
Demo
There is a lot more information specific to each widget, located in its documentation. For now, here is a cool showcase of this part of pytermgui.
import sys
import pytermgui as ptg
with ptg.alt_buffer():
root = ptg.Container(
ptg.Label("[210 bold]This is a title"),
ptg.Label(""),
ptg.Label("[italic grey]This is some body text. It is very interesting."),
ptg.Label(),
ptg.Button("[red]Stop application!", onclick=lambda *_: sys.exit()),
ptg.Button("[green]Do nothing"),
)
root.center().print()
while True:
root.handle_key(ptg.getch())
root.print()
1""" 2The widget system. 3 4Basic concept 5------------- 6 7Everything starts with the `Widget` class. It represents a single part 8of the overarching system. Simple widgets like `Label` simply implement 9a `get_lines` method, in which they can come up with what to display as. 10 11The more complex type widget is something like `Container`. This widget holds 12other widgets within itself, and uses some fancy logic to display them 13in a neat and organized way. 14 15 16Magic methods 17------------- 18 19Most widgets support a selection of magic methods, also known as dunders. 20For example, all `Container` children are iterable by default, and allow 21adding elements using the `+=` operator. You can also index into them, if 22that floats your boat. 23 24 25Demo 26---- 27 28There is a lot more information specific to each widget, located in its 29documentation. For now, here is a cool showcase of this part of pytermgui. 30 31```python3 32import sys 33import pytermgui as ptg 34 35with ptg.alt_buffer(): 36 root = ptg.Container( 37 ptg.Label("[210 bold]This is a title"), 38 ptg.Label(""), 39 ptg.Label("[italic grey]This is some body text. It is very interesting."), 40 ptg.Label(), 41 ptg.Button("[red]Stop application!", onclick=lambda *_: sys.exit()), 42 ptg.Button("[green]Do nothing"), 43 ) 44 45 root.center().print() 46 47 while True: 48 root.handle_key(ptg.getch()) 49 root.print() 50``` 51 52<p style="text-align: center"> 53 <img 54 src="https://raw.githubusercontent.com/bczsalba/pytermgui/master/assets/docs/ 55 widgets/demo.png" width=100%> 56</p>""" 57 58from __future__ import annotations 59 60from typing import Optional, Type, Union 61 62from . import boxes 63from .base import * 64from .button import Button 65from .checkbox import Checkbox 66from .collapsible import * 67from .color_picker import ColorPicker 68from .containers import * 69from .input_field import InputField 70from .keyboard_button import KeyboardButton 71from .pixel_matrix import * 72from .slider import Slider 73from .styles import * 74from .toggle import Toggle 75 76WidgetType = Union[Widget, Type[Widget]] 77 78 79class _IDManager: 80 """Simple object to store all widgets in a program, and 81 allow referencing by id.""" 82 83 def __init__(self) -> None: 84 """Initialize dict""" 85 86 self._widgets: dict[str, WidgetType] = {} 87 88 def register(self, other: Widget) -> None: 89 """Add widget to self._widgets 90 91 This method is meant to be called only internally by Widget.""" 92 93 objid = other.id 94 95 if objid is None: 96 raise ValueError("Cannot register element with no ID!") 97 98 self._widgets[objid] = other 99 100 def deregister(self, key: str) -> None: 101 """Remove widget from self._widgets 102 103 This method is meant to be called only internally by Widget.""" 104 105 del self._widgets[key] 106 107 def get_id(self, other: Widget) -> Optional[str]: 108 """Check if a widget has been registered""" 109 110 for key, widget in self._widgets.items(): 111 if widget == other: 112 return key 113 114 return None 115 116 def get_widget(self, widget_id: str) -> Optional[WidgetType]: 117 """Get widget by id""" 118 119 return self._widgets.get(widget_id) 120 121 122_manager = _IDManager() 123setattr(Widget, "_id_manager", _manager) 124 125get_widget = _manager.get_widget 126get_id = _manager.get_id
117 def get_widget(self, widget_id: str) -> Optional[WidgetType]: 118 """Get widget by id""" 119 120 return self._widgets.get(widget_id)
Get widget by id
108 def get_id(self, other: Widget) -> Optional[str]: 109 """Check if a widget has been registered""" 110 111 for key, widget in self._widgets.items(): 112 if widget == other: 113 return key 114 115 return None
Check if a widget has been registered