0
# File Loading and Serialization
1
2
PyTermGUI provides comprehensive file loading and serialization capabilities for widget configuration management, including YAML and JSON support for creating widgets from configuration files and persisting widget states.
3
4
## Capabilities
5
6
### File Loaders
7
8
Base file loading system with support for different formats and widget namespace management.
9
10
```python { .api }
11
class FileLoader:
12
"""Base file loader for widget configuration."""
13
14
def __init__(self):
15
"""Initialize file loader."""
16
17
def load(self, path: str) -> "WidgetNamespace":
18
"""
19
Load widget configuration from file.
20
21
Parameters:
22
- path (str): Path to configuration file
23
24
Returns:
25
WidgetNamespace containing loaded widgets
26
"""
27
28
def save(self, namespace: "WidgetNamespace", path: str):
29
"""
30
Save widget namespace to file.
31
32
Parameters:
33
- namespace (WidgetNamespace): Widgets to save
34
- path (str): Output file path
35
"""
36
37
class YamlLoader(FileLoader):
38
"""YAML file loader for widget configuration."""
39
40
def load(self, path: str) -> "WidgetNamespace":
41
"""
42
Load widgets from YAML file.
43
44
Parameters:
45
- path (str): Path to YAML file
46
47
Returns:
48
WidgetNamespace with loaded widgets
49
50
Requires:
51
PyYAML package (pip install PyYAML)
52
"""
53
54
class JsonLoader(FileLoader):
55
"""JSON file loader for widget configuration."""
56
57
def load(self, path: str) -> "WidgetNamespace":
58
"""
59
Load widgets from JSON file.
60
61
Parameters:
62
- path (str): Path to JSON file
63
64
Returns:
65
WidgetNamespace with loaded widgets
66
"""
67
```
68
69
### Widget Namespace
70
71
Container for managing collections of loaded widgets with name-based access.
72
73
```python { .api }
74
class WidgetNamespace:
75
"""Container for loaded widget configurations."""
76
77
def __init__(self, widgets: dict[str, Widget] = None):
78
"""
79
Create widget namespace.
80
81
Parameters:
82
- widgets (dict, optional): Named widget collection
83
"""
84
85
def __getitem__(self, name: str) -> Widget:
86
"""Get widget by name."""
87
88
def __setitem__(self, name: str, widget: Widget):
89
"""Set named widget."""
90
91
def __contains__(self, name: str) -> bool:
92
"""Check if widget name exists."""
93
94
@property
95
def widgets(self) -> dict[str, Widget]:
96
"""Get all widgets as dictionary."""
97
98
def add(self, name: str, widget: Widget):
99
"""Add named widget to namespace."""
100
101
def remove(self, name: str) -> Widget:
102
"""Remove and return named widget."""
103
104
def list_names(self) -> list[str]:
105
"""Get list of all widget names."""
106
```
107
108
### Serialization System
109
110
Widget serialization for saving and loading widget states and configurations.
111
112
```python { .api }
113
class Serializer:
114
"""Widget serialization and deserialization system."""
115
116
def __init__(self):
117
"""Initialize serializer."""
118
119
def dump(self, widget: Widget) -> dict:
120
"""
121
Serialize widget to dictionary.
122
123
Parameters:
124
- widget (Widget): Widget to serialize
125
126
Returns:
127
Dictionary representation of widget
128
"""
129
130
def load(self, data: dict) -> Widget:
131
"""
132
Deserialize widget from dictionary.
133
134
Parameters:
135
- data (dict): Serialized widget data
136
137
Returns:
138
Reconstructed widget instance
139
"""
140
141
def dump_to_file(self, widget: Widget, filename: str):
142
"""Save widget to file."""
143
144
def load_from_file(self, filename: str) -> Widget:
145
"""Load widget from file."""
146
147
# Global serializer instance
148
serializer: Serializer
149
```
150
151
## Configuration File Formats
152
153
### YAML Configuration
154
155
Example YAML widget configuration format:
156
157
```yaml
158
# widgets.yaml
159
main_window:
160
type: Window
161
title: "My Application"
162
width: 60
163
height: 20
164
widgets:
165
- type: Label
166
value: "[bold]Welcome to PyTermGUI"
167
- type: Container
168
widgets:
169
- type: Button
170
label: "Click Me"
171
onclick: "handle_click"
172
- type: InputField
173
prompt: "Enter text:"
174
value: ""
175
176
settings_dialog:
177
type: Window
178
title: "Settings"
179
width: 40
180
height: 15
181
widgets:
182
- type: Checkbox
183
label: "Enable sound"
184
checked: true
185
- type: Slider
186
min_value: 0
187
max_value: 100
188
value: 50
189
```
190
191
### JSON Configuration
192
193
Example JSON widget configuration format:
194
195
```json
196
{
197
"main_form": {
198
"type": "Container",
199
"width": 50,
200
"widgets": [
201
{
202
"type": "Label",
203
"value": "[210 bold]User Registration"
204
},
205
{
206
"type": "InputField",
207
"prompt": "Username:",
208
"id": "username_field"
209
},
210
{
211
"type": "InputField",
212
"prompt": "Password:",
213
"id": "password_field"
214
},
215
{
216
"type": "Button",
217
"label": "Register",
218
"onclick": "handle_register"
219
}
220
]
221
}
222
}
223
```
224
225
## Usage Examples
226
227
### Loading Widgets from YAML
228
229
```python
230
import pytermgui as ptg
231
232
# Load widgets from YAML file
233
loader = ptg.YamlLoader()
234
namespace = loader.load("widgets.yaml")
235
236
# Access loaded widgets by name
237
main_window = namespace["main_window"]
238
settings_dialog = namespace["settings_dialog"]
239
240
# Use in window manager
241
with ptg.WindowManager() as manager:
242
manager.add(main_window)
243
```
244
245
### Loading Widgets from JSON
246
247
```python
248
import pytermgui as ptg
249
250
# Load from JSON configuration
251
loader = ptg.JsonLoader()
252
namespace = loader.load("forms.json")
253
254
# Get specific widget
255
form = namespace["main_form"]
256
257
# Add to application
258
with ptg.WindowManager() as manager:
259
window = ptg.Window(form, title="Registration")
260
manager.add(window)
261
```
262
263
### Widget Serialization
264
265
```python
266
import pytermgui as ptg
267
268
# Create widget hierarchy
269
container = ptg.Container(
270
"[bold]Settings Panel",
271
"",
272
ptg.Checkbox(checked=True, label="Enable notifications"),
273
ptg.Slider(value=75, min_value=0, max_value=100),
274
ptg.Button("Save", lambda btn: print("Saved")),
275
width=40
276
)
277
278
# Serialize widget to dictionary
279
widget_data = ptg.serializer.dump(container)
280
print(widget_data)
281
282
# Save to file
283
ptg.serializer.dump_to_file(container, "settings.json")
284
285
# Later, load widget back
286
restored_container = ptg.serializer.load_from_file("settings.json")
287
```
288
289
### Dynamic Widget Creation
290
291
```python
292
import pytermgui as ptg
293
294
def create_form_from_config(config_file):
295
"""Create form widgets from configuration."""
296
loader = ptg.JsonLoader()
297
namespace = loader.load(config_file)
298
299
forms = {}
300
for name, widget in namespace.widgets.items():
301
if isinstance(widget, ptg.Container):
302
forms[name] = widget
303
304
return forms
305
306
# Load multiple forms
307
forms = create_form_from_config("forms.json")
308
309
# Create tabbed interface
310
current_form = "login"
311
312
def switch_form(form_name):
313
global current_form
314
current_form = form_name
315
# Update display logic here
316
317
# Use forms in application
318
with ptg.WindowManager() as manager:
319
window = ptg.Window(
320
forms[current_form],
321
title="Forms Demo"
322
)
323
manager.add(window)
324
```
325
326
### Configuration with Callbacks
327
328
```python
329
import pytermgui as ptg
330
331
# Define callback functions
332
def handle_submit(button):
333
print("Form submitted!")
334
335
def handle_cancel(button):
336
print("Form cancelled!")
337
338
# Callback registry for configuration files
339
CALLBACKS = {
340
"handle_submit": handle_submit,
341
"handle_cancel": handle_cancel
342
}
343
344
def load_with_callbacks(config_file):
345
"""Load widgets and bind callbacks."""
346
loader = ptg.JsonLoader()
347
namespace = loader.load(config_file)
348
349
# Process widgets to bind callbacks
350
for widget in namespace.widgets.values():
351
bind_callbacks_recursive(widget)
352
353
return namespace
354
355
def bind_callbacks_recursive(widget):
356
"""Recursively bind callbacks to widgets."""
357
if hasattr(widget, 'onclick') and isinstance(widget.onclick, str):
358
# Replace string callback name with actual function
359
callback_name = widget.onclick
360
if callback_name in CALLBACKS:
361
widget.onclick = CALLBACKS[callback_name]
362
363
# Process child widgets
364
if hasattr(widget, 'widgets'):
365
for child in widget.widgets:
366
bind_callbacks_recursive(child)
367
368
# Usage
369
namespace = load_with_callbacks("interface.json")
370
```
371
372
### Saving Widget State
373
374
```python
375
import pytermgui as ptg
376
377
class StatefulForm:
378
"""Form that can save and restore its state."""
379
380
def __init__(self):
381
self.form = ptg.Container(
382
"[bold]Stateful Form",
383
"",
384
ptg.InputField(prompt="Name:", id="name"),
385
ptg.InputField(prompt="Email:", id="email"),
386
ptg.Checkbox(id="newsletter", label="Newsletter"),
387
"",
388
ptg.Button("Save State", self.save_state),
389
ptg.Button("Load State", self.load_state),
390
width=50
391
)
392
393
def save_state(self, button):
394
"""Save current form state."""
395
ptg.serializer.dump_to_file(self.form, "form_state.json")
396
print("State saved!")
397
398
def load_state(self, button):
399
"""Restore form state."""
400
try:
401
restored_form = ptg.serializer.load_from_file("form_state.json")
402
# Update current form with restored values
403
self.update_form_values(restored_form)
404
print("State loaded!")
405
except FileNotFoundError:
406
print("No saved state found")
407
408
def update_form_values(self, restored_form):
409
"""Update form with restored values."""
410
# Implementation depends on specific widget ID matching
411
for widget in restored_form.widgets:
412
if hasattr(widget, 'id') and widget.id:
413
current_widget = self.find_widget_by_id(widget.id)
414
if current_widget:
415
# Copy values from restored widget
416
if hasattr(widget, 'value'):
417
current_widget.value = widget.value
418
if hasattr(widget, 'checked'):
419
current_widget.checked = widget.checked
420
421
# Usage
422
form = StatefulForm()
423
```