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