Исходный код EJIO.ctk_extender.components.login_form
## /ctk_extender/components/login_form.py
import customtkinter as ctk
from typing import Any
from EJIO.utils import _
from ..widget import Form, FormCheckBox, Button, PackStrategy
from ..event import on_event, EventController
from .event import FieldReturnEvent
from .labeled_field import FormLabeledField
__all__ = [
'LoginForm',
]
[документация]
class LoginForm(Form):
"""
Высокоуровневый составной компонент формы авторизации.
"""
__slots__ = ()
def __init__(self, parent: Any, geometry: Any = None) -> None:
super().__init__(parent, geometry)
self._populate_form_components()
[документация]
def build(self) -> ctk.CTkFrame:
frame_instance = super().build()
frame_instance.configure(fg_color="transparent")
return frame_instance
def _populate_form_components(self) -> None:
# 1. Добавляем поле Логина
login_widget = self.add_widget(
FormLabeledField,
name="login",
label_text=_("ctk_extender.builtins.component.login_form.login_text"),
placeholder=_("ctk_extender.builtins.component.login_form.login_placeholder"),
layout="column",
required=False,
geometry=PackStrategy(fill="x", pady=(0, 10))
)
# 2. Добавляем поле Пароля
pass_widget = self.add_widget(
FormLabeledField,
name="password",
label_text=_("ctk_extender.builtins.component.login_form.password_text"),
placeholder=_("ctk_extender.builtins.component.login_form.password_placeholder"),
layout="column",
required=False,
show="•",
geometry=PackStrategy(fill="x", pady=(0, 15))
)
# 3. Добавляем чекбокс "Запомнить меня"
self.add_widget(
FormCheckBox,
name="remember_me",
text=_("ctk_extender.builtins.component.login_form.remember_text"),
geometry=PackStrategy(anchor="w", pady=(0, 20))
)
# 4. Добавляем кастомную кнопку отправки
self.add_widget(
Button,
text=_("ctk_extender.builtins.component.login_form.btn_text"),
command=self.submit,
geometry=PackStrategy(fill="x")
)
# Перехватываем низкоуровневый Enter инпутов и сразу транслируем в шину событий.
# Добираемся к нативным инпутам через цепочки _field_instance базовых оберток
login_widget._field_instance.ctk_instance.bind( #TODO: добавить функционал для быстрой установки событий через обертку
"<Return>", lambda e: EventController.emit(FieldReturnEvent(self,"login"))
)
pass_widget._field_instance.ctk_instance.bind(
"<Return>", lambda e: EventController.emit(FieldReturnEvent(self,"password"))
)
@on_event(FieldReturnEvent, predicate=lambda e: e.sender.__class__.__name__ == "LoginForm")
def _handle_internal_return(self, event: FieldReturnEvent) -> None:
"""Переключает фокус по цепочке полей, используя focus_field."""
if event.sender != self:
return
if event.field_name == "login":
self.focus_field("password")
elif event.field_name == "password":
self.submit()