Исходный код 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()