Исходный код EJIO.ctk_extender.widget.form.fields.directory

## /ctk_extender/widget/form/fields/directory.py

import customtkinter as ctk
from tkinter import filedialog
from typing import Any
from .base import InputField
from ...container import WidgetContainer
from ...components import Label
from ...geometry import GridStrategy

__all__ = ['FormDirectoryField']


[документация] class FormDirectoryField(WidgetContainer, InputField): """Поле формы для выбора директорий с поддержкой валидации и ограничений.""" __slots__ = ('_name', '_label_text', '_file_types', '_multiple', '_required', '_value', '_entry', '_btn') def __init__( self, parent: Any, name: str, label_text: str, required: bool = False, geometry: Any = None, **kwargs: Any ) -> None: self._name: str = name self._label_text: str = label_text self._required: bool = required self._value: str = "" self._entry: ctk.CTkEntry | None = None self._btn: ctk.CTkButton | None = None super().__init__(parent, geometry, **kwargs)
[документация] def build(self) -> ctk.CTkFrame: frame = super().build() frame.configure(fg_color="transparent") # 1. Текстовая подпись self.add_widget(Label, text=self._label_text, geometry=GridStrategy(row=0, column=0, sticky="w", padx=(0, 10))) # Контейнер для инпута и кнопки row_frame = ctk.CTkFrame(frame, fg_color="transparent") row_frame.grid(row=0, column=1, sticky="ew") frame.grid_columnconfigure(1, weight=1) # 2. Неизменяемое поле вывода пути self._entry = ctk.CTkEntry(row_frame, font=("Consolas", 11), state="disabled") self._entry.pack(side="left", fill="x", expand=True, padx=(0, 5)) # 3. Кнопка вызова проводника self._btn = ctk.CTkButton(row_frame, text="📁", width=36, height=28, command=self._browse) self._btn.pack(side="right") return frame
def _browse(self) -> None: master = self.ctk_instance.winfo_toplevel() path = filedialog.askdirectory(title=self._label_text, master=master) #TODO: посмотреть изменения if path: self._value = path self._update_ui(path) def _update_ui(self, text: str) -> None: if self._entry: self._entry.configure(state="normal") self._entry.delete(0, "end") self._entry.insert(0, text) self._entry.configure(state="disabled") @property def name(self) -> str: return self._name
[документация] def get_value(self) -> str | list[str]: return self._value
[документация] def set_value(self, value: Any) -> None: pass
[документация] def clear(self) -> None: self._value = "" if not self._multiple else [] self._update_ui("")
[документация] def validate(self) -> str | None: if self._required and not self._value: return f"Field '{self._label_text}' required to fill out." return None