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