Загрузка данных
"""
Микро-зачет: Архитектура настольных приложений, Tkinter GUI, события, несколько страниц.
Архитектура:
- Модель (данные) хранится в виде переменных внутри контроллера.
- Представление (View) — класс App, который строит интерфейс.
- Контроллер (App) объединяет модель и представление, обрабатывает события.
Такое разделение упрощает поддержку и расширение.
"""
import tkinter as tk
from tkinter import ttk
class App:
"""Главное приложение с двумя страницами (фреймами)."""
def __init__(self, root):
self.root = root
self.root.title("Микро-зачет: Tkinter + несколько страниц")
self.root.geometry("500x400")
self.root.resizable(False, False)
# Модель: просто храним данные, введенные пользователем
self.user_data = ""
# Создаем контейнер для страниц (стек фреймов)
self.container = ttk.Frame(root)
self.container.pack(fill="both", expand=True)
# Словарь для хранения страниц (фреймов)
self.frames = {}
# Создаем страницы
self.create_frames()
# Показываем первую страницу (главную)
self.show_frame("MainPage")
def create_frames(self):
"""Создает все страницы приложения."""
# Страница 1: Главная
main_frame = MainPage(self.container, self)
self.frames["MainPage"] = main_frame
main_frame.grid(row=0, column=0, sticky="nsew")
# Страница 2: Информация
info_frame = InfoPage(self.container, self)
self.frames["InfoPage"] = info_frame
info_frame.grid(row=0, column=0, sticky="nsew")
def show_frame(self, page_name):
"""Переключает видимую страницу."""
frame = self.frames[page_name]
frame.tkraise() # поднимает выбранный фрейм наверх
def save_data(self, text):
"""Обновляет модель данными (пример обработки события)."""
self.user_data = text
print(f"Сохранено в модели: {self.user_data}")
def get_data(self):
"""Возвращает данные из модели."""
return self.user_data
class MainPage(ttk.Frame):
"""Главная страница: ввод данных и обработка событий."""
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
# Заголовок
ttk.Label(self, text="Главная страница", font=("Arial", 16)).pack(pady=10)
# Поле ввода
ttk.Label(self, text="Введите текст:").pack(pady=5)
self.entry = ttk.Entry(self, width=40)
self.entry.pack(pady=5)
self.entry.bind("<Return>", self.on_enter) # событие нажатия Enter
# Кнопка сохранения
save_btn = ttk.Button(self, text="Сохранить", command=self.save_text)
save_btn.pack(pady=5)
# Кнопка перехода на страницу информации
info_btn = ttk.Button(self, text="Перейти на страницу информации",
command=lambda: controller.show_frame("InfoPage"))
info_btn.pack(pady=10)
# Метка для отображения текущих данных
self.display_label = ttk.Label(self, text="Сохранённые данные: (нет)")
self.display_label.pack(pady=20)
# Обновляем метку при каждом показе страницы
self.bind("<Visibility>", self.on_visibility)
def save_text(self):
"""Обработчик события нажатия кнопки 'Сохранить'."""
text = self.entry.get()
if text.strip():
self.controller.save_data(text)
self.update_display()
self.entry.delete(0, tk.END) # очищаем поле
else:
# Обработка ошибки: просто показываем в консоли, можно добавить всплывающее окно
print("Ошибка: поле ввода пустое")
def on_enter(self, event):
"""Обработчик события нажатия Enter в поле ввода."""
self.save_text()
def update_display(self):
"""Обновляет метку с текущими данными."""
data = self.controller.get_data()
self.display_label.config(text=f"Сохранённые данные: {data if data else '(нет)'}")
def on_visibility(self, event):
"""Вызывается, когда страница становится видимой."""
self.update_display()
class InfoPage(ttk.Frame):
"""Страница с информацией и кнопкой возврата."""
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
ttk.Label(self, text="Информация", font=("Arial", 16)).pack(pady=10)
ttk.Label(self, text="Это пример интерфейса с двумя страницами.\n"
"На главной странице вы можете ввести текст и сохранить его.\n"
"Модель данных хранится в контроллере (класс App).\n"
"Переключение страниц реализовано через tkraise().",
justify="center", wraplength=400).pack(pady=20)
# Кнопка возврата на главную
back_btn = ttk.Button(self, text="На главную",
command=lambda: controller.show_frame("MainPage"))
back_btn.pack(pady=10)
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
root.mainloop()