Загрузка данных
# modules/about_window.py
import tkinter as tk
from tkinter import ttk
from pathlib import Path
try:
# Для Python 3.11+
from PIL import Image, ImageTk
except ImportError:
Image = None
def show_about(parent):
"""
Создает модальное окно "О программе" с изображением и информацией о приложении.
:param parent: ссылка на главное окно (root)
"""
about = tk.Toplevel(parent)
about.title("О программе")
about.resizable(False, False)
# Настройка стилей для отступов (опционально, но делает вид аккуратнее)
style = ttk.Style(about)
style.configure("Info.TLabel", padding=(10, 5))
# --- Главный контейнер ---
main_frame = ttk.Frame(about, padding="15")
main_frame.pack(fill=tk.BOTH, expand=True)
# --- Левый фрейм: Изображение ---
left_frame = ttk.Frame(main_frame)
left_frame.pack(side=tk.LEFT, fill=tk.Y)
logo_label = ttk.Label(left_frame)
logo_label.pack()
image_path = Path(file).parent / "Сова2.png"
if Image and image_path.exists():
try:
# Открываем и приводим к нужному размеру, чтобы не растягивать интерфейс
img = Image.open(image_path)
img.thumbnail((120, 120))
photo = ImageTk.PhotoImage(img)
# Важно сохранить ссылку на объект изображения, иначе оно не отобразится
logo_label.image = photo
logo_label.config(image=photo)
except Exception:
logo_label.config(text="Изображение\nне загружено")
else:
logo_label.config(text="Логотип\nСова2.png", relief=tk.RIDGE, width=15)
# --- Правый фрейм: Атрибуты ---
right_frame = ttk.Frame(main_frame)
right_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(15, 0))
# Заголовок приложения жирным шрифтом
title_label = ttk.Label(right_frame, text="Мое приложение", font=('Segoe UI', 12, 'bold'))
title_label.pack(anchor=tk.W, pady=(0, 10))
# Список основных атрибутов
info_data = [
("Версия:", "v3.0.1"),
("Сборка:", "#2026.07.01"),
("Разработчик:", "Юрий Балыко"),
("Python:", f"{platform.python_version()}"),
]
for key, value in info_data:
# Ключи выравниваются по правому краю, значения — по левому
row_frame = ttk.Frame(right_frame)
row_frame.pack(fill=tk.X, pady=2)
key_label = ttk.Label(row_frame, text=key, width=12, anchor=tk.E, style="Info.TLabel")
key_label.pack(side=tk.LEFT)
val_label = ttk.Label(row_frame, text=value, anchor=tk.W, style="Info.TLabel")
val_label.pack(side=tk.LEFT, fill=tk.X, expand=True)
# Ссылка на сайт или почту (синий подчеркнутый текст)
link_var = tk.StringVar(value="support@example.com")
link_label = ttk.Label(right_frame, textvariable=link_var, cursor="hand2", foreground="blue")
link_label.pack(anchor=tk.W, pady=(10, 0))
link_label.bind("<Button-1>", lambda e: print(f"Кликнули по ссылке: {link_var.get()}"))
# Разделитель
ttk.Separator(right_frame, orient='horizontal').pack(fill=tk.X, pady=10)
# Кнопка закрытия
close_btn = ttk.Button(right_frame, text="Закрыть", command=about.destroy)
close_btn.pack(pady=5)
# --- Модальность окна ---
about.transient(parent)
about.grab_set()
# Центрируем относительно родительского окна
parent.update_idletasks()
about.update_idletasks()
win_width = about.winfo_reqwidth()
win_height = about.winfo_reqheight()
par_x = parent.winfo_rootx()
par_y = parent.winfo_rooty()
par_w = parent.winfo_width()
par_h = parent.winfo_height()
pos_x = par_x + (par_w // 2) - (win_width // 2)
pos_y = par_y + (par_h // 2) - (win_height // 2)
about.geometry(f"+{pos_x}+{pos_y}")
# Блокируем основной поток до закрытия окна
about.wait_window()