/
O.S.Prog
/
InstrumentProtocol
Обзор
Документация
Войти
/
O.S.Prog
/
InstrumentProtocol
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
ui/settings_window.py
405 строк
17 KB
O.S.Prog
Initial commit: InstrumentProtocol v2.0
17 июл 2026, 15:11
17 июл 2026, 15:11
1e845bd
Код
Авторство
О чём код?
from PyQt6.QtWidgets import * from PyQt6.QtCore import * from core.settings_manager import SettingsManager import os class SettingsWindow(QDialog): def __init__(self, parent=None, open_phrases_tab=False, open_templates_tab=False, login=""): super().__init__(parent) self.login = login self.setWindowTitle("Настройки") self.setGeometry(200, 200, 550, 550) self.setModal(True) self.settings = SettingsManager() layout = QVBoxLayout() self.tabs = QTabWidget() # ===== Вкладка 1: Общие настройки ===== general_tab = QWidget() general_layout = QFormLayout() # Лечебное учреждение hospital_layout = QVBoxLayout() self.hospital_combo = QComboBox() self.hospital_combo.setEditable(True) self.hospital_combo.setInsertPolicy(QComboBox.InsertPolicy.NoInsert) self.hospital_combo.setStyleSheet("font-size: 14px; padding: 5px;") hospital_history = self.settings.get_history("hospital_history") for h in hospital_history: self.hospital_combo.addItem(h) last_hospital = self.settings.get_last_hospital() if last_hospital: self.hospital_combo.setCurrentText(last_hospital) hospital_layout.addWidget(self.hospital_combo) hosp_btn_layout = QHBoxLayout() self.new_hospital_input = QLineEdit() self.new_hospital_input.setPlaceholderText("Введите название нового учреждения...") hosp_btn_layout.addWidget(self.new_hospital_input) btn_add_hospital = QPushButton("+ Добавить") btn_add_hospital.clicked.connect(self.add_hospital) hosp_btn_layout.addWidget(btn_add_hospital) btn_del_hospital = QPushButton("🗑️ Удалить") btn_del_hospital.clicked.connect(self.remove_hospital) hosp_btn_layout.addWidget(btn_del_hospital) hospital_layout.addLayout(hosp_btn_layout) general_layout.addRow("Лечебное учреждение:", hospital_layout) self.auto_squeeze_check = QCheckBox("Включить авто-сжатие при печати") self.auto_squeeze_check.setChecked(self.settings.get("auto_squeeze", True)) general_layout.addRow(self.auto_squeeze_check) self.min_font_input = QSpinBox() self.min_font_input.setRange(8, 14) self.min_font_input.setValue(self.settings.get("min_font_size", 10)) general_layout.addRow("Минимальный шрифт при печати:", self.min_font_input) general_tab.setLayout(general_layout) # Папка для экспорта PDF pdf_layout = QHBoxLayout() pdf_layout.addWidget(QLabel("Папка для экспорта PDF:")) self.pdf_folder_input = QLineEdit() self.pdf_folder_input.setPlaceholderText("Введите путь или выберите папку...") self.pdf_folder_input.setText(self.settings.get("pdf_export_folder", "")) pdf_layout.addWidget(self.pdf_folder_input) btn_pdf_browse = QPushButton("Обзор...") btn_pdf_browse.clicked.connect(self.select_pdf_folder) pdf_layout.addWidget(btn_pdf_browse) general_layout.addRow("", pdf_layout) # ===== Вкладка 2: Часто используемые фразы ===== phrases_tab = QWidget() phrases_layout = QVBoxLayout() # Выбор типа исследования type_phrases_layout = QHBoxLayout() type_phrases_layout.addWidget(QLabel("Тип исследования:")) self.phrases_type_combo = QComboBox() self.phrases_type_combo.addItems(self._get_all_research_types()) self.phrases_type_combo.currentTextChanged.connect(self.load_phrases) type_phrases_layout.addWidget(self.phrases_type_combo) type_phrases_layout.addStretch() phrases_layout.addLayout(type_phrases_layout) self.phrases_list = QListWidget() phrases_layout.addWidget(self.phrases_list) self.new_phrase_input = QLineEdit() self.new_phrase_input.setPlaceholderText("Введите новую фразу...") phrases_layout.addWidget(self.new_phrase_input) btn_layout = QHBoxLayout() btn_add = QPushButton("+ Добавить фразу") btn_add.clicked.connect(self.add_phrase) btn_remove = QPushButton("- Удалить фразу") btn_remove.clicked.connect(self.remove_phrase) btn_layout.addWidget(btn_add) btn_layout.addWidget(btn_remove) btn_layout.addStretch() phrases_layout.addLayout(btn_layout) phrases_tab.setLayout(phrases_layout) self.load_phrases() self.tabs.addTab(general_tab, "Основные") self.tabs.addTab(phrases_tab, "Фразы") # Если нужно открыть на вкладке Фразы if open_phrases_tab: self.tabs.setCurrentIndex(1) layout.addWidget(self.tabs) # ===== Вкладка 3: Шаблоны протоколов ===== templates_tab = QWidget() templates_layout = QVBoxLayout() from core.templates_manager import TemplatesManager self.templates_manager = TemplatesManager() # Выбор типа исследования type_templates_layout = QHBoxLayout() type_templates_layout.addWidget(QLabel("Тип исследования:")) self.templates_type_combo = QComboBox() self.templates_type_combo.addItems(self._get_all_research_types()) self.templates_type_combo.currentTextChanged.connect(self.load_templates) type_templates_layout.addWidget(self.templates_type_combo) type_templates_layout.addStretch() templates_layout.addLayout(type_templates_layout) self.templates_list = QListWidget() self.templates_list.itemClicked.connect(self.on_template_selected) templates_layout.addWidget(self.templates_list) self.template_preview = QTextEdit() self.template_preview.setReadOnly(True) self.template_preview.setPlaceholderText("Выберите шаблон для просмотра...") templates_layout.addWidget(QLabel("Просмотр шаблона:")) templates_layout.addWidget(self.template_preview) btn_layout = QHBoxLayout() btn_add_template = QPushButton("+ Добавить шаблон") btn_add_template.clicked.connect(self.add_template) btn_remove_template = QPushButton("- Удалить шаблон") btn_remove_template.clicked.connect(self.remove_template) btn_layout.addWidget(btn_add_template) btn_layout.addWidget(btn_remove_template) btn_layout.addStretch() templates_layout.addLayout(btn_layout) templates_tab.setLayout(templates_layout) self.tabs.addTab(templates_tab, "Шаблоны") self.load_templates() # Кнопки buttons = QHBoxLayout() btn_save = QPushButton("Сохранить") btn_save.clicked.connect(self.save_settings) btn_cancel = QPushButton("Выход") btn_cancel.clicked.connect(self.reject) buttons.addWidget(btn_save) buttons.addWidget(btn_cancel) layout.addLayout(buttons) self.setLayout(layout) if open_phrases_tab: self.tabs.setCurrentIndex(1) if open_templates_tab: self.tabs.setCurrentIndex(2) def add_phrase(self): phrase = self.new_phrase_input.text().strip() if phrase: self.phrases_list.addItem(phrase) self.new_phrase_input.clear() self._save_phrases() def remove_phrase(self): current = self.phrases_list.currentItem() if current: self.phrases_list.takeItem(self.phrases_list.row(current)) self._save_phrases() def _save_phrases(self): """Сохраняет фразы для текущего типа""" key = self._get_phrases_key() phrases = [self.phrases_list.item(i).text() for i in range(self.phrases_list.count())] self.settings.set(key, phrases) def save_settings(self): hospital = self.hospital_combo.currentText().strip() # Сохраняем историю hospital_history = [self.hospital_combo.itemText(i) for i in range(self.hospital_combo.count())] self.settings.settings["hospital_history"] = hospital_history if hospital: self.settings.set("hospital_name", hospital) pdf_folder = self.pdf_folder_input.text().strip() import os if pdf_folder: if not os.path.exists(pdf_folder): try: os.makedirs(pdf_folder, exist_ok=True) QMessageBox.information(self, "Создано", f"Папка создана:\n{pdf_folder}") except Exception as e: QMessageBox.critical(self, "Ошибка", f"Не удалось создать папку:\n{str(e)}") return self.settings.set("pdf_export_folder", pdf_folder) self.settings.set("auto_squeeze", self.auto_squeeze_check.isChecked()) self.settings.set("min_font_size", self.min_font_input.value()) self.settings.save_settings() QMessageBox.information(self, "Успех", "Настройки сохранены") def select_pdf_folder(self): """Выбирает папку для экспорта PDF (как в резервном копировании)""" from PyQt6.QtWidgets import QDialog, QVBoxLayout, QLabel, QLineEdit, QPushButton, QHBoxLayout, QMessageBox, QFileDialog import os current_path = self.pdf_folder_input.text().strip() if not current_path: current_path = os.path.expanduser("~/Documents") dialog = QDialog(self) dialog.setWindowTitle("Выбор папки для PDF") dialog.setModal(True) dialog.setGeometry(300, 300, 600, 180) layout = QVBoxLayout() label = QLabel("Укажите папку для экспорта PDF:") layout.addWidget(label) path_input = QLineEdit() path_input.setText(current_path) path_input.setPlaceholderText("Введите путь или выберите папку...") layout.addWidget(path_input) btn_layout = QHBoxLayout() btn_browse = QPushButton("Обзор...") btn_browse.clicked.connect(lambda: path_input.setText(QFileDialog.getExistingDirectory(self, "Выберите папку", path_input.text()))) btn_layout.addWidget(btn_browse) btn_layout.addStretch() layout.addLayout(btn_layout) btn_layout2 = QHBoxLayout() btn_ok = QPushButton("Выбрать") btn_ok.setStyleSheet("background-color: #27ae60; color: white; font-weight: bold; padding: 8px; border-radius: 5px;") btn_cancel = QPushButton("Отмена") def on_ok(): folder = path_input.text().strip() if not folder: folder = current_path # Проверяем существование папки if not os.path.exists(folder): reply = QMessageBox.question( dialog, "Создать папку?", f"Папка '{folder}' не существует.\n\nСоздать её?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No ) if reply == QMessageBox.StandardButton.No: return try: os.makedirs(folder, exist_ok=True) QMessageBox.information(dialog, "Создано", f"Папка создана:\n{folder}") except Exception as e: QMessageBox.critical(dialog, "Ошибка", f"Не удалось создать папку: {str(e)}") return self.pdf_folder_input.setText(folder) dialog.accept() btn_ok.clicked.connect(on_ok) btn_cancel.clicked.connect(dialog.reject) btn_layout2.addWidget(btn_ok) btn_layout2.addWidget(btn_cancel) layout.addLayout(btn_layout2) dialog.setLayout(layout) dialog.exec() def _get_all_research_types(self): """Собирает все типы исследований""" types = ["Рентген", "УЗИ", "ФГС", "ЭКГ", "МРТ", "МСКТ/КТ", "Спирография"] custom = self.settings.get("custom_research_types", []) return types + custom def _get_phrases_key(self): current_type = self.phrases_type_combo.currentText() key = f"phrases_{self.login}_{current_type}" return key def _get_templates_key(self): """Ключ для хранения шаблонов в настройках""" current_type = self.templates_type_combo.currentText() return f"templates_{self.login}_{current_type}" def load_phrases(self): """Загружает фразы для выбранного типа""" self.phrases_list.clear() key = self._get_phrases_key() phrases = self.settings.get(key, []) for phrase in phrases: self.phrases_list.addItem(phrase) def load_templates(self): """Загружает шаблоны для выбранного типа""" self.templates_list.clear() self.template_preview.clear() key = self._get_templates_key() templates = self.settings.get(key, {}) for name in templates: self.templates_list.addItem(name) def on_template_selected(self, item): """Показывает текст шаблона при выборе""" name = item.text() key = self._get_templates_key() templates = self.settings.get(key, {}) text = templates.get(name, "") self.template_preview.setText(text) def add_template(self): """Добавляет новый шаблон через редактор""" from ui.template_editor import TemplateEditor editor = TemplateEditor(self) if editor.exec(): name = editor.get_name() text = editor.get_text() if name and text: key = self._get_templates_key() templates = self.settings.get(key, {}) if name in templates: reply = QMessageBox.question( self, "Шаблон уже существует", f"Шаблон '{name}' уже существует. Заменить?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No ) if reply == QMessageBox.StandardButton.No: return templates[name] = text self.settings.set(key, templates) self.load_templates() QMessageBox.information(self, "Добавлено", f"Шаблон '{name}' добавлен.") def remove_template(self): """Удаляет выбранный шаблон""" current = self.templates_list.currentItem() if current: name = current.text() reply = QMessageBox.question( self, "Удалить шаблон?", f"Удалить шаблон '{name}'?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No ) if reply == QMessageBox.StandardButton.Yes: key = self._get_templates_key() templates = self.settings.get(key, {}) if name in templates: del templates[name] self.settings.set(key, templates) self.load_templates() QMessageBox.information(self, "Удалено", f"Шаблон '{name}' удалён.") def add_hospital(self): name = self.new_hospital_input.text().strip() if name: existing = [self.hospital_combo.itemText(i) for i in range(self.hospital_combo.count())] if name in existing: QMessageBox.warning(self, "Уже есть", f"Учреждение '{name}' уже в списке.") return # Добавляем и сортируем items = [self.hospital_combo.itemText(i) for i in range(self.hospital_combo.count())] items.append(name) items.sort(key=lambda x: x.lower()) self.hospital_combo.clear() for item in items: self.hospital_combo.addItem(item) self.hospital_combo.setCurrentText(name) self.new_hospital_input.clear() def remove_hospital(self): index = self.hospital_combo.currentIndex() if index >= 0: self.hospital_combo.removeItem(index)