/
sc_p
/
EnergoAI
Обзор
Документация
Войти
/
sc_p
/
EnergoAI
Код
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
ui/gui.py
295 строк
10 KB
Павел Щёголев
Загрузить файлы в «»
12 мар 2026, 04:54
Верифицирован
12 мар 2026, 04:54
628f0d6
Код
Авторство
О чём код?
import tkinter as tk from tkinter import filedialog, messagebox from core.sandbox_state import SandboxState from ui.sandbox_view import SandboxView from ui.base_text_input import attach_text_input_behaviour from ui.token_dialog import TokenDialog from ui.ui_tools import UITool class AppGUI(tk.Tk): def __init__(self, on_send_chat, sandbox_state: SandboxState, show_sandbox=True): super().__init__() self.configure(bg="#1e1e1e") self.title("ИИ-ассистент для энергетических расчетов") self.geometry("1000x750") self.protocol("WM_DELETE_WINDOW", self.destroy) self.on_send_chat = on_send_chat self.ui_tools = self._build_ui_tools() self.sandbox_state = None self.show_sandbox = show_sandbox self._create_menu() self.main_container = tk.Frame(self, bg="#1e1e1e") self.main_container.pack(fill="both", expand=True, padx=10, pady=10) self._create_header() self._create_chat_panel() if self.show_sandbox: self._create_sandbox_panel() else: self.chat_history_frame.pack_configure(padx=10, pady=10) self.chat_history.tag_config("bold", font=("Arial", 11, "bold")) self.chat_history.tag_config("lightblue", foreground="lightblue") self.chat_history.tag_config("lightgreen", foreground="lightgreen") self.chat_history.tag_config("yellow", foreground="yellow") self.chat_history.tag_config("system", foreground="orange", font=("Arial", 10, "italic")) self.sandbox_panel_created = self.show_sandbox def _create_menu(self): menubar = tk.Menu(self) self.config(menu=menubar) view_menu = tk.Menu(menubar, tearoff=0, bg="#2b2b2b", fg="white") menubar.add_cascade(label="Вид", menu=view_menu) self.sandbox_var = tk.BooleanVar(value=self.show_sandbox) view_menu.add_checkbutton( label="Показать Python Sandbox", variable=self.sandbox_var, command=self._toggle_sandbox, background="#2b2b2b", foreground="white", activebackground="#2b2b2b", activeforeground="white" ) tools_menu = tk.Menu(menubar, tearoff=0, bg="#2b2b2b", fg="white") menubar.add_cascade(label="Инструменты", menu=tools_menu) tools_menu.add_command( label="Ввести токен...", command=self._show_token_dialog, background="#2b2b2b", foreground="white" ) tools_menu.add_command( label="Очистить историю чата", command=self._clear_chat_history, background="#2b2b2b", foreground="white" ) help_menu = tk.Menu(menubar, tearoff=0, bg="#2b2b2b", fg="white") menubar.add_cascade(label="Справка", menu=help_menu) help_menu.add_command( label="О программе", command=self._show_about, background="#2b2b2b", foreground="white" ) def _create_header(self): header_frame = tk.Frame(self.main_container, bg="#2b2b2b", height=60) header_frame.pack(fill="x", padx=10, pady=(10, 5)) header_frame.pack_propagate(False) title_label = tk.Label( header_frame, text="ИИ-ассистент для энергетических расчетов", font=("Arial", 16, "bold"), fg="lightgreen", bg="#2b2b2b" ) title_label.pack(pady=15) sandbox_status = "включен" if self.show_sandbox else "отключен" self.status_label = tk.Label( header_frame, text=f"Python Sandbox: {sandbox_status}", font=("Arial", 10), fg="lightblue", bg="#2b2b2b" ) self.status_label.pack(pady=(0, 10)) def _create_chat_panel(self): self.chat_panel = tk.Frame(self.main_container, bg="#2b2b2b") self.chat_panel.pack(side="left", fill="both", expand=True) self.chat_history_frame = tk.Frame(self.chat_panel, bg="#2b2b2b") self.chat_history_frame.pack(fill="both", expand=True) self.chat_history = tk.Text( self.chat_history_frame, wrap="word", font=("Arial", 11), bg="#1e1e1e", fg="white", insertbackground="white" ) attach_text_input_behaviour(self.chat_history, self) scrollbar = tk.Scrollbar( self.chat_history_frame, command=self.chat_history.yview ) self.chat_history.config(yscrollcommand=scrollbar.set) self.chat_history.pack( side="left", fill="both", expand=True, padx=(10, 0), pady=10 ) scrollbar.pack( side="right", fill="y", pady=10 ) self._create_input_panel(parent=self.chat_panel) def _show_chat_context_menu(self, event): try: self.chat_input.focus_set() self.chat_menu.tk_popup(event.x_root, event.y_root) finally: self.chat_menu.grab_release() def _create_input_panel(self, parent): entry_frame = tk.Frame(parent, bg="#2b2b2b") entry_frame.pack(fill="x", padx=10, pady=5) self.chat_input = tk.Text( entry_frame, height=4, wrap="word", font=("Arial", 11), bg="#3c3c3c", fg="white", insertbackground="white" ) self.chat_input.pack(side="left", fill="x", expand=True, padx=(0, 6)) attach_text_input_behaviour(self.chat_input, self) def _on_keypress(event): # Shift+Enter → новая строка if event.keysym == "Return" and (event.state & 0x0001): self.chat_input.insert("insert", "\n") return "break" # Enter → отправка if event.keysym == "Return": self._send_chat() return "break" self.chat_input.bind("<KeyPress-Return>", _on_keypress) send_btn = tk.Button( entry_frame, text="Отправить", command=self._send_chat, font=("Arial", 11, "bold"), bg="#007acc", fg="white", activebackground="#005a9e", height=2, width=10 ) send_btn.pack(side="right") def _create_sandbox_panel(self): self.right_panel = tk.Frame(self.main_container, bg="#2b2b2b", width=350) self.right_panel.pack(side="right", fill="y", padx=(5, 0)) sandbox_header = tk.Label( self.right_panel, text="Python Sandbox", font=("Arial", 13, "bold"), fg="yellow", bg="#2b2b2b" ) sandbox_header.pack(pady=10) self.sandbox_view = SandboxView(self.right_panel) self.sandbox_view.pack(fill="both", expand=True, padx=10, pady=10) def _toggle_sandbox(self): self.show_sandbox = self.sandbox_var.get() if self.show_sandbox: if not hasattr(self, "right_panel"): self._create_sandbox_panel() else: self.right_panel.pack(side="right", fill="y", padx=(5, 0)) self.add_chat("Система", "Python Sandbox включен") else: if hasattr(self, "right_panel"): self.right_panel.pack_forget() self.add_chat("Система", "Python Sandbox отключен") def add_chat(self, who: str, text: str): color = "lightblue" if who == "Вы" else "lightgreen" if who == "Бот" else "yellow" role_display = "" self.chat_history.insert("end", f"{who}{role_display}: ", ("bold", color)) if who == "Система": self.chat_history.insert("end", f"{text}\n\n", "system") else: self.chat_history.insert("end", f"{text}\n\n") self.chat_history.see("end") def _send_chat(self): text = self.chat_input.get("1.0", "end").strip() if not text: return self.on_send_chat(text) self.chat_input.delete("1.0", "end") def _clear_chat_history(self): self.chat_history.delete("1.0", "end") self.add_chat("Система", "История чата очищена") def refresh_sandbox(self): if hasattr(self, 'sandbox_view'): self.sandbox_view.update_stdout(self.sandbox_state.stdout) def _show_token_dialog(self): def on_token_submit(token): self.add_chat("Система", f"Токен принят. Роль: {self._get_role_display_name(self.current_role)}") self.add_chat("Система", "Теперь можно общаться с ИИ-ассистентом.") TokenDialog(self, on_submit=on_token_submit) def _show_about(self): about_text = """ИИ-ассистент для энергетической отрасли Особенности: • ИИ-ассистент на базе GigaChat • Безопасный Python sandbox • Инструменты для энергетической отрасли • Сохранение истории диалогов """ messagebox.showinfo("О программе", about_text) return "Информация о программе показана." def _build_ui_tools(self): return [ UITool( name="clear_chat_ui", description="Очищает историю чата в интерфейсе", handler=lambda _: self._clear_chat_history() ), UITool( name="show_about_ui", description="Показывает информацию о программе", handler=lambda _: self._show_about() ), ]