Загрузка данных
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import os
from modules.administrator.admin_ui import AdminPanel
class MainInterface(tk.Tk):
def __init__(self):
super().__init__()
self.current_user = {"login": None}
# === ТОЛЬКО ГЕОМЕТРИЯ И ВИДЖЕТЫ ===
self.geometry("458x360")
self.resizable(False, False)
bg_color = "#EEEEEE"
self.configure(bg=bg_color)
main_frame = tk.Frame(self, bg=bg_color)
main_frame.pack(padx=1, pady=1, fill='both', expand=True)
button_width = 20
button_height = 2
button_font = ("Arial", 12, "bold")
for i in range(7):
main_frame.grid_rowconfigure(i, weight=0)
main_frame.grid_columnconfigure(0, minsize=210, weight=0)
main_frame.grid_columnconfigure(1, minsize=235, weight=0)
# --- ЛЕВАЯ ПАНЕЛЬ ---
left_buttons = [
("Администратор", self._show_admin_menu),
#("Менеджер базы", self._show_manager_menu),
#("Эксперты", self._show_experts_menu),
#("Проект", self._show_project_menu),
#("Прогнозирование", self._show_forecast_menu)
]
for row_index, (btn_text, command_func) in enumerate(left_buttons):
btn = tk.Button(
main_frame,
text=btn_text,
font=button_font,
width=button_width,
height=button_height,
anchor="w",
command=command_func
)
btn.grid(row=row_index, column=0, padx=5, pady=5, sticky="ew")
# --- ПРАВАЯ ПАНЕЛЬ ---
right_box = tk.Frame(main_frame, bg=bg_color, width=235, height=300)
right_box.grid(row=0, column=1, rowspan=6, pady=5, sticky="nsew", padx=(0, 5))
right_box.grid_propagate(False)
right_box.columnconfigure(0, weight=1)
picture_frame = tk.Frame(right_box, bg="#d9ead3", highlightbackground="gray",
highlightthickness=1, width=225, height=160)
picture_frame.place(relx=0.5, y=5, anchor="n")
picture_frame.grid_propagate(False)
current_dir = os.path.dirname(os.path.abspath(__file__))
image_path = os.path.join(current_dir, "images", "Сова1.png")
try:
original_img = Image.open(image_path)
target_w, target_h = 215, 130
img_ratio = original_img.width / original_img.height
box_ratio = target_w / target_h
if img_ratio > box_ratio:
new_w, new_h = target_w, int(target_w / img_ratio)
else:
new_w, new_h = int(target_h * img_ratio), target_h
resized_img = original_img.resize((new_w, new_h), resample=Image.LANCZOS)
self.tk_image = ImageTk.PhotoImage(resized_img)
label = tk.Label(picture_frame, image=self.tk_image, bg="#d9ead3", borderwidth=0)
label.image = self.tk_image
label.place(relx=0.5, rely=0.5, anchor='center', width=new_w, height=new_h)
except Exception as e:
print(f"[FATAL IMAGE ERROR]: {e}")
canvas = tk.Canvas(picture_frame, width=225, height=160, bg="red", highlightthickness=0)
canvas.create_text(112, 80, text="IMG\nFAIL", fill="white")
canvas.place(x=0, y=0, relwidth=1, relheight=1)
spacer = tk.Frame(right_box, bg=bg_color, height=1)
spacer.grid(row=0, column=0, pady=(170, 10), sticky="ew")
upper_padding = tk.Frame(right_box, bg=bg_color, height=3)
upper_padding.grid(row=1, column=0)
btn6 = tk.Button(right_box, text="Руководство", font=button_font, width=button_width, height=button_height)
btn6.grid(row=2, column=0, ipadx=10, pady=(0, 5), sticky="ew")
btn7 = tk.Button(right_box, text="О программе", font=button_font, width=button_width, height=button_height)
btn7.grid(row=3, column=0, ipadx=10, pady=(5, 15), sticky="ew")
footer_frame = tk.Frame(main_frame, bg="#0078D7")
footer_frame.grid(row=6, column=0, columnspan=2, sticky="ew", pady=(10, 0))
footer_label = tk.Label(footer_frame, text="Copyright © Минск, НИИ, 2027 год", fg="#FF8C00",
bg="#0078D7", font=("Arial", 12, "bold"))
footer_label.pack(expand=True, ipady=4)
# --- КОНТЕЙНЕРЫ ДЛЯ ПОДМЕНЮ ---
self.menu_container = tk.Frame(main_frame, bg=bg_color)
self.menu_container.grid_rowconfigure(0, weight=1)
self.menu_container.grid_columnconfigure(0, weight=1)
def _create_menu_panel(container, title_text):
panel = tk.Frame(container, bg="#f0f0f0", bd=2, relief="sunken")
panel.grid_propagate(False)
header_frame = tk.Frame(panel, bg="#4a4a4a", height=30)
header_frame.pack(fill='x')
close_btn = tk.Button(
header_frame,
text="← Назад",
font=("Arial", 9),
fg="white",
bg="#888888",
borderwidth=0,
command=self._show_main_screen
)
close_btn.pack(side='right', padx=5, pady=2)
content_frame = tk.Frame(panel, bg="#f0f0f0")
content_frame.pack(fill='both', expand=True, padx=10, pady=10)
ttk.Label(content_frame, text=f"Здесь будет функционал:\n{title_text}").pack(expand=True)
return panel
self.admin_panel = _create_menu_panel(self.menu_container, "Подменю Администратор")
self.manager_panel = _create_menu_panel(self.menu_container, "Подменю Менеджер базы")
self.experts_panel = _create_menu_panel(self.menu_container, "Подменю Эксперты")
self.project_panel = _create_menu_panel(self.menu_container, "Подменю Проект")
self.forecast_panel = _create_menu_panel(self.menu_container, "Подменю Прогнозирование")
self.guide_panel = _create_menu_panel(self.menu_container, "Подменю Руководство")
self.about_panel = _create_menu_panel(self.menu_container, "Подменю О программе")
self._current_menu_visible = None
# --- МЕТОД ВОЗВРАТА НА ГЛАВНЫЙ ЭКРАН ---
def _show_main_screen(self):
self._hide_current_menu()
self.menu_container.grid_remove()
self.grid_columnconfigure(0, minsize=210, weight=0)
self.grid_columnconfigure(1, minsize=235, weight=0)
def _hide_current_menu(self):
print("[LOG] Скрываем текущее меню...")
# Если есть админ-панель, убиваем её полностью
if hasattr(self, 'admin_panel') and self.admin_panel:
self.admin_panel.destroy()
self.admin_panel = None
# Проходимся по всем детям контейнера и уничтожаем их
for child in self.menu_container.winfo_children():
child.destroy()
self._current_menu_visible = None
print("[LOG] Меню скрыто.")
# --- ОБРАБОТЧИКИ КНОПОК (БЕЗ .title()) ---
def _show_admin_menu(self):
print("[LOG] Нажата кнопка 'Администратор'.")
# Прячем всё, что было в контейнере до этого (сову, кнопки, серый фон)
self._hide_current_menu()
try:
from modules.administrator.admin_ui import AdminPanel
# Создаем фасад ПРЯМО В ГЛАВНОМ ОКНЕ (self), а не во вложенном фрейме.
# Это гарантирует, что он перекроет все внутренние элементы.
self.admin_panel = AdminPanel(self, current_user=self.current_user)
# Размещаем его поверх ВСЕГО главного окна с помощью .place().
# relwidth=1 и relheight=1 означают "займи 100% ширины и высоты родителя".
self.admin_panel.place(relx=0, rely=0, relwidth=1, relheight=1)
# Поднимаем Z-index, чтобы точно быть выше картинок.
self.admin_panel.lift()
# Принудительно просим Tkinter перерисовать окно СЕЙЧАС,
# чтобы лайм/светло-серый цвет появился мгновенно.
self.update_idletasks()
self._current_menu_visible = 'admin'
print("[LOG] Фасад Администратора успешно размещен.")
except Exception as e:
print(f"[FATAL ERROR] Не удалось создать панель администратора: {e}")
def _show_manager_menu(self):
print("[LOG] Нажата кнопка 'Менеджер базы'.")
self._hide_current_menu()
try:
# Импортируем НОВЫЙ класс
from modules.manager.manager_ui import ManagerPanel
# Создаем его точно так же, как делали AdminPanel
self.manager_panel = ManagerPanel(self.menu_container, current_user=self.current_user)
# Размещаем через place поверх всего контейнера
self.manager_panel.place(relx=0, rely=0, relwidth=1, relheight=1)
self.manager_panel.tkraise()
self.update_idletasks()
self._current_menu_visible = 'manager'
except Exception as e:
print(f"[FATAL] {e}")
def _show_experts_menu(self):
self._show_main_screen()
self.menu_container.grid(row=0, column=0, rowspan=6, columnspan=2, sticky="nsew")
self.experts_panel.grid(row=0, column=0, sticky="nsew")
self._current_menu_visible = 'experts'
def _show_project_menu(self):
self._show_main_screen()
self.menu_container.grid(row=0, column=0, rowspan=6, columnspan=2, sticky="nsew")
self.project_panel.grid(row=0, column=0, sticky="nsew")
self._current_menu_visible = 'project'
def _show_forecast_menu(self):
self._show_main_screen()
self.menu_container.grid(row=0, column=0, rowspan=6, columnspan=2, sticky="nsew")
self.forecast_panel.grid(row=0, column=0, sticky="nsew")
self._current_menu_visible = 'forecast'
def _show_guide_menu(self):
self._show_main_screen()
self.menu_container.grid(row=0, column=0, rowspan=6, columnspan=2, sticky="nsew")
self.guide_panel.grid(row=0, column=0, sticky="nsew")
self._current_menu_visible = 'guide'
def _show_about_menu(self):
self._show_main_screen()
self.menu_container.grid(row=0, column=0, rowspan=6, columnspan=2, sticky="nsew")
self.about_panel.grid(row=0, column=0, sticky="nsew")
self._current_menu_visible = 'about'
def switch_user_radical(self):
root_win = self.winfo_toplevel()
from modules.utils.app_state import disable_app
disable_app(root_win)
if hasattr(self, 'current_user'):
self.current_user = {"login": None}
if hasattr(self, '_child_windows'):
self._child_windows.clear()
try:
root_win.destroy()
except Exception:
pass
import sys, subprocess, os, shutil
script_path = os.path.abspath("main.py")
gui_python = shutil.which("pythonw.exe")
if not gui_python:
current_dir = os.path.dirname(sys.executable)
potential_path = os.path.join(current_dir, "pythonw.exe")
gui_python = potential_path if os.path.exists(potential_path) else sys.executable
try:
subprocess.Popen([gui_python, script_path], shell=True, creationflags=subprocess.CREATE_NO_WINDOW if os.name == 'nt' else 0)
except Exception as e:
print(f"[FATAL] Не удалось запустить новую копию Dozor: {e}")
sys.exit(0)