Виджеты¶
Виджеты - компоненты, из которых строится содержимое окна (Window). Все виджеты делятся на текстовые, клавиатурные, медиа-виджеты и поля ввода.
Текстовые виджеты¶
Отвечают за текстовое содержимое сообщения.
Const¶
Статический текст, который не зависит от данных.
from maxo.dialogs.widgets.text import Const
Const("Добро пожаловать в бота!")
Format¶
Динамический текст с форматированием через .format(). Ключи подставляются из словаря, возвращённого геттером.
from maxo.dialogs.widgets.text import Format
# В геттере: return {"name": "Иван", "balance": 100}
Format("Привет, {name}! Твой баланс: {balance} ₽")
Jinja¶
Шаблоны Jinja2. Подходят для сложной логики рендеринга с условиями и циклами.
from maxo.dialogs.widgets.text import Jinja
Jinja("""
Привет, {{ user.name }}!
{% if user.is_admin %}🔑 Вы администратор{% endif %}
""")
Multi и Case¶
Multi отображает несколько текстовых виджетов друг за другом.
Case выбирает один из вариантов в зависимости от значения ключа из данных.
from maxo.dialogs.widgets.text import Case, Const, Format, Multi
Multi(
Const("Добро пожаловать!"),
Format("Текущий язык: {lang}"),
)
# selector - ключ из данных геттера, texts - варианты
Case(
texts={
"en": Const("Hello!"),
"ru": Const("Привет!"),
},
selector="lang",
)
Клавиатурные виджеты¶
Используются для создания Inline-кнопок.
Url¶
Кнопка-ссылка. При нажатии открывает URL.
from maxo.dialogs.widgets.kbd import Url
from maxo.dialogs.widgets.text import Const
Url(Const("Открыть сайт"), Const("https://example.com"))
Clipboard¶
Кнопка, при нажатии на которую в буфер обмена пользователя копируется переданный текст.
from maxo.dialogs.widgets.kbd import Clipboard
from maxo.dialogs.widgets.text import Const
Clipboard(Const("Скопировать"), Const("Текст для копирования"))
Row, Column, Group¶
Группировка кнопок в строку, столбец или произвольную группу.
from maxo.dialogs.widgets.kbd import Button, Column, Group, Row
from maxo.dialogs.widgets.text import Const
# Две кнопки в одной строке
Row(
Button(Const("Да"), id="yes", on_click=on_click),
Button(Const("Нет"), id="no", on_click=on_click),
)
# Три кнопки в столбец (каждая в своей строке)
Column(
Button(Const("Первый"), id="b1", on_click=on_click),
Button(Const("Второй"), id="b2", on_click=on_click),
Button(Const("Третий"), id="b3", on_click=on_click),
)
# Group с фиксированной шириной (2 кнопки в строке)
Group(
Button(Const("A"), id="a", on_click=on_click),
Button(Const("B"), id="b", on_click=on_click),
Button(Const("C"), id="c", on_click=on_click),
Button(Const("D"), id="d", on_click=on_click),
width=2,
)
Select¶
Список выбора: динамически генерирует кнопки из данных.
from maxo.dialogs.api.protocols import DialogManager
from maxo.dialogs.widgets.kbd import Select
from maxo.dialogs.widgets.text import Format
from maxo.routing.updates import MessageCallback
async def on_fruit_selected(callback: MessageCallback, widget: Select, manager: DialogManager, item_id: str):
await callback.callback_answer(f"Вы выбрали: {item_id}")
# items - ключ из данных геттера (list[tuple[str, str]])
# В геттере: return {"fruits": [("apple", "🍎 Яблоко"), ("banana", "🍌 Банан")]}
Select(
Format("{item[1]}"), # текст кнопки
id="fruit_select",
item_id_getter=lambda item: item[0], # ID элемента
items="fruits", # ключ из данных
on_click=on_fruit_selected,
)
Radio¶
Переключатель - позволяет выбрать один элемент из списка. Выбранный элемент отмечается.
from maxo.dialogs.widgets.kbd import Radio
from maxo.dialogs.widgets.text import Format
Radio(
Format("✅ {item[1]}"), # текст для выбранного
Format(" {item[1]}"), # текст для невыбранного
id="lang_radio",
item_id_getter=lambda item: item[0],
items="languages",
# В геттере: return {"languages": [("ru", "Русский"), ("en", "English")]}
)
TimeSelect¶
Виджет для выбора времени (часы и минуты). Представляет собой две отдельные клавиатуры для выбора часов и минут, что позволяет пользователю легко ввести нужное время.
Использование¶
from datetime import time
from maxo.dialogs import Dialog, DialogManager, Window
from maxo.dialogs.widgets.kbd import TimeSelect
from maxo.dialogs.widgets.text import Const
from maxo.fsm import State, StatesGroup
class MySG(StatesGroup):
time_selection = State()
async def on_time_selected(event, widget, manager: DialogManager, selected_time: time):
# Здесь можно обработать выбранное время
await event.callback_answer(f"Вы выбрали время: {selected_time.strftime('%H:%M')}")
manager.dialog_data["selected_time"] = selected_time
dialog = Dialog(
Window(
Const("Выберите время:"),
TimeSelect(
id="time_selector",
on_value_changed=on_time_selected,
),
state=MySG.time_selection,
)
)
Параметры¶
id (
str): Уникальный идентификатор виджета.when (
WhenCondition, optional): Условие, при котором виджет будет отображаться.hour_header (
TextWidget, optional): Текст заголовка для выбора часов. По умолчанию «Hour».minute_header (
TextWidget, optional): Текст заголовка для выбора минут. По умолчанию «Minute».button_text (
TextWidget, optional): Формат текста для кнопок часов/минут, которые не выбраны. По умолчанию «{value}».button_selected_text (
TextWidget, optional): Формат текста для выбранных кнопок часов/минут. По умолчанию «[{value}]».on_hour_click (
OnClick, optional): Обработчик нажатия на кнопку часа.on_minute_click (
OnClick, optional): Обработчик нажатия на кнопку минуты.on_value_changed (
OnValueChanged, optional): Обработчик изменения выбранного времени. Принимает аргументыevent,widget,manager,value: datetime.time.hour_width (
int, optional): Количество кнопок часов в одной строке. По умолчанию 6.minute_precision (
int, optional): Шаг для минут (например, 5 для 0, 5, 10… минут). По умолчанию 5.minute_width (
int, optional): Количество кнопок минут в одной строке. По умолчанию 6.
Управление виджетом (ManagedTimeSelect)¶
Вы можете получить или установить выбранное время программно с помощью ManagedTimeSelect, который доступен через widget в обработчиках, или через manager.find(widget_id).get_value().
get_value() -> datetime.time | None: Возвращает выбранное время или
None, если ничего не выбрано.set_value(value: datetime.time | None): Устанавливает выбранное время.
Навигационные кнопки¶
Готовые кнопки для переключения между окнами без написания обработчиков:
from maxo.dialogs.widgets.kbd import Next, Back, SwitchTo
from maxo.dialogs.widgets.text import Const
# Следующее окно (по порядку объявления в Dialog)
Next(Const("Далее →"), id="next")
# Предыдущее окно
Back(Const("← Назад"), id="back")
# Переключиться на конкретное состояние
SwitchTo(Const("В настройки"), id="to_settings", state=SG.settings)
Прочие виджеты¶
DynamicMedia / StaticMedia¶
Окно может содержать медиа (фото, видео, документ). Вы можете возвращать URL или ID файла.
from maxo.dialogs.widgets.media import DynamicMedia
async def media_getter(dialog_manager, **kwargs):
return {"photo_url": "https://example.com/photo.jpg"}
# Предполагается использование в Window с getter=media_getter
MessageInput¶
Слушает текстовые сообщения от пользователя, находясь в конкретном окне. Используется для сбора свободного текстового ввода.
from maxo.dialogs.widgets.input import MessageInput
async def on_message(message, widget, manager):
manager.dialog_data["user_input"] = message.text
await manager.next()
Window(
Const("Введите ваше имя:"),
MessageInput(on_message),
state=SG.input_name,
)