diff --git a/ComConfigCopy.py b/ComConfigCopy.py index 9a9a0a3..8f5d8a8 100644 --- a/ComConfigCopy.py +++ b/ComConfigCopy.py @@ -695,17 +695,33 @@ class TerminalWidget(CustomText): pady=5, spacing1=2, # Отступ перед абзацем spacing2=2, # Межстрочный интервал - spacing3=2 # Отступ после абзаца + spacing3=2, # Отступ после абзаца + state='disabled' # Делаем виджет только для чтения ) # Счетчик команд для разделителей self.command_counter = 0 + + # Отключаем возможность вставки текста + self.bind('<>', lambda e: 'break') + self.bind('', self._readonly) + + # Изменяем контекстное меню + self.context_menu.delete("Вырезать") + self.context_menu.delete("Вставить") + + def _readonly(self, event): + """Обработчик для блокировки ввода""" + return 'break' def append_text(self, text, message_type=None): """ Добавление текста с определенным типом сообщения message_type может быть: 'error', 'warning', 'info', 'command' """ + # Временно разрешаем изменение для добавления текста + self.config(state='normal') + # Добавляем текст if not text.endswith('\n'): text += '\n' @@ -721,6 +737,9 @@ class TerminalWidget(CustomText): # Автоматическая прокрутка к концу self.see(tk.END) + # Возвращаем состояние "только для чтения" + self.config(state='disabled') + # Обновляем виджет self.update_idletasks() @@ -738,6 +757,9 @@ class TerminalWidget(CustomText): def append_command(self, text): """Добавление команды с разделителем""" + # Временно разрешаем изменение для добавления текста + self.config(state='normal') + # Добавляем разделитель между командами if self.command_counter > 0: self.insert(tk.END, "\n" + "─" * 80 + "\n", "separator") @@ -745,10 +767,15 @@ class TerminalWidget(CustomText): # Добавляем команду self.append_text(text, "command") + + # Возвращаем состояние "только для чтения" + self.config(state='disabled') def clear(self): """Очистка терминала""" + self.config(state='normal') self.delete("1.0", tk.END) + self.config(state='disabled') self.command_counter = 0 # Основной класс для графического интерфейса @@ -944,6 +971,14 @@ class SerialAppGUI(tk.Tk): ) disconnect_btn.pack(side=LEFT, padx=5) + # Кнопка очистки терминала + clear_btn = ttk.Button( + control_frame, + text="🗑 Очистить", # Unicode символ для "корзины" + command=lambda: self.interactive_text.clear() + ) + clear_btn.pack(side=LEFT, padx=5) + # Используем новый TerminalWidget вместо CustomText self.interactive_text = TerminalWidget(frame, height=20) self.interactive_text.pack(fill=BOTH, expand=True, padx=5, pady=5) @@ -1107,6 +1142,10 @@ class SerialAppGUI(tk.Tk): self.stop_button = ttk.Button(control_frame, text="⏹ Остановить", command=self.stop_execution, state="disabled") self.stop_button.pack(side=LEFT, padx=5) + # Кнопка очистки терминала + self.clear_button = ttk.Button(control_frame, text="🗑 Очистить", command=lambda: self.file_exec_text.clear()) + self.clear_button.pack(side=LEFT, padx=5) + # Создаем фрейм для индикатора прогресса и таймера progress_frame = ttk.Frame(frame) progress_frame.pack(fill=X, pady=5, padx=5) @@ -1197,20 +1236,30 @@ class SerialAppGUI(tk.Tk): def check_connection(): """Проверка состояния соединения""" + # Если выполнение остановлено пользователем, просто возвращаем False без сообщений + if self.execution_stop: + return False + if not self.connection or not self.connection.is_open: + # Если остановка произошла во время проверки, не показываем сообщение + if self.execution_stop: + return False + self.append_file_exec_text("[ERROR] Соединение потеряно!\n") # Автоматически ставим на паузу self.execution_paused = True self.after(0, lambda: self.pause_button.config(text="▶ Продолжить")) - # Показываем сообщение пользователю - self.after(0, lambda: messagebox.showerror( - "Ошибка соединения", - "Соединение с устройством потеряно!\nВыполнение команд приостановлено.\n\n" - "Пожалуйста:\n" - "1. Проверьте подключение\n" - "2. Нажмите 'Продолжить' после восстановления соединения\n" - " или 'Остановить' для прекращения выполнения" - )) + + # Показываем сообщение только если это не ручная остановка + if not self.execution_stop: + self.after(0, lambda: messagebox.showerror( + "Ошибка соединения", + "Соединение с устройством потеряно!\nВыполнение команд приостановлено.\n\n" + "Пожалуйста:\n" + "1. Проверьте подключение\n" + "2. Нажмите 'Продолжить' после восстановления соединения\n" + " или 'Остановить' для прекращения выполнения" + )) return False return True @@ -1582,6 +1631,14 @@ class SerialAppGUI(tk.Tk): state="disabled" ) self.stop_tftp_button.pack(side=LEFT, padx=5) + + # Кнопка очистки лога + self.clear_tftp_button = ttk.Button( + buttons_frame, + text="🗑 Очистить лог", + command=lambda: self.tftp_log_text.clear() + ) + self.clear_tftp_button.pack(side=LEFT, padx=5) # Лог сервера log_frame = ttk.LabelFrame(tftp_frame, text="Лог сервера")