Исходный код EJIO.ctk_extender.components.labeled_field
## /ctk_extender/components/labeled_field.py
import customtkinter as ctk
from typing import Any, Literal
from ..widget import WidgetContainer, Label, InputField, FormTextField, GeometryStrategy, GridStrategy
__all__ = [
'FormLabeledField',
]
FieldLayout = Literal['row', 'column']
[документация]
class FormLabeledField(WidgetContainer, InputField):
"""
Высокоуровневый составной компонент формы.
Строится на базе WidgetContainer и использует внутри себя готовый FormTextField.
"""
__slots__ = ('_name', '_label_text', '_placeholder', '_layout', '_required', '_kwargs', '_field_instance')
def __init__(
self,
parent: Any,
name: str,
label_text: str,
placeholder: str = "",
layout: FieldLayout = 'row',
required: bool = False,
geometry: GeometryStrategy | None = None,
**kwargs: Any
) -> None:
self._name: str = name
self._label_text: str = label_text
self._placeholder: str = placeholder
self._layout: FieldLayout = layout
self._required: bool = required
self._kwargs: dict[str, Any] = kwargs
# Ссылка на внутренний компонент поля ввода, который сделает всю работу
self._field_instance: FormTextField | None = None
super().__init__(parent, geometry)
self._populate_field_components()
[документация]
def build(self) -> ctk.CTkFrame:
"""
Строит базовый фрейм контейнера и декларативно наполняет его
написанными ранее компонентами.
"""
frame_instance = super().build()
frame_instance.configure(fg_color="transparent")
return frame_instance
def _populate_field_components(self) -> None:
frame_instance = self.ctk_instance
lbl = self.add_widget(Label, text=self._label_text)
self._field_instance = self.add_widget(
FormTextField,
name=self._name,
placeholder=self._placeholder,
required=self._required,
**self._kwargs
)
# Выстраиваем сетку в зависимости от выбранного режима отображения
if self._layout == 'row':
lbl.set_geometry(GridStrategy(row=0, column=0, sticky="w", padx=(0, 10), pady=2))
self._field_instance.set_geometry(GridStrategy(row=0, column=1, sticky="ew", pady=2))
frame_instance.grid_columnconfigure(1, weight=1)
else:
lbl.set_geometry(GridStrategy(row=0, column=0, sticky="w", pady=(0, 2)))
self._field_instance.set_geometry(GridStrategy(row=1, column=0, sticky="ew", pady=(0, 2)))
frame_instance.grid_columnconfigure(0, weight=1)
[документация]
def focus(self) -> None:
"""Перенаправляет фокус ввода внутреннему текстовому полю формы."""
if self._field_instance is not None:
self._field_instance.focus()
@property
def name(self) -> str:
return self._name
[документация]
def get_value(self) -> str:
if self._field_instance is None:
return ""
return self._field_instance.get_value()
[документация]
def set_value(self, value: Any) -> None:
if self._field_instance is not None:
self._field_instance.set_value(value)
[документация]
def clear(self) -> None:
if self._field_instance is not None:
self._field_instance.clear()
[документация]
def validate(self) -> str | None:
if self._field_instance is None:
return None
return self._field_instance.validate()
[документация]
def destroy(self) -> None:
"""Каскадно очищает ссылки и вызывает базовое уничтожение контейнера."""
self._field_instance = None
super().destroy()