from PyQt5.QtWidgets import QFileDialog, QMessageBox, QTableWidgetItem, QComboBox from model import Reagent class Controller: def __init__(self, view, model): self.view = view self.model = model self.setup_connections() def setup_connections(self): """Подключает сигналы виджетов к методам контроллера""" self.view.add_row_btn.clicked.connect(self.add_reagent_row) self.view.remove_row_btn.clicked.connect(self.remove_reagent_row) self.view.calculate_btn.clicked.connect(self.calculate) self.view.save_btn.clicked.connect(self.save_composition) self.view.load_btn.clicked.connect(self.load_composition) # Авторасчёт при изменении количества среды self.view.amount_input.valueChanged.connect(self.calculate) # Авторасчёт при смене единицы измерения self.view.amount_unit_combo.currentTextChanged.connect(self.calculate) def add_reagent_row(self): """Добавляет новую строку в таблицу реагентов с предустановленными значениями""" row = self.view.table.rowCount() self.view.table.insertRow(row) self.view.table.setItem(row, 0, QTableWidgetItem("Реагент")) self.view.table.setItem(row, 1, QTableWidgetItem("1.0")) unit_combo = QComboBox() unit_combo.addItems(["нг", "мкг", "мг", "г", "кг", "нл", "мкл", "мл", "л"]) unit_combo.setCurrentText("мг") self.view.table.setCellWidget(row, 2, unit_combo) self.view.table.setItem(row, 3, QTableWidgetItem("1.0")) self.view.table.setItem(row, 4, QTableWidgetItem("")) def remove_reagent_row(self): """Удаляет выделенную строку из таблицы реагентов и из модели""" current_row = self.view.table.currentRow() if current_row >= 0: self.view.table.removeRow(current_row) if 0 <= current_row < len(self.model.reagents): del self.model.reagents[current_row] def calculate(self): """Выполняет расчёт количеств реагентов и растворителя""" try: self._update_model_from_view() results = self.model.calculate_amounts() self.view.update_results(results) except ValueError as e: self.view.show_error(f"Ошибка в данных: {str(e)}") except Exception as e: self.view.show_error(f"Неожиданная ошибка: {str(e)}") def _update_model_from_view(self): """Обновляет модель данными из интерфейса""" self.model.reagents.clear() self.model.total_amount = self.view.amount_input.value() self.model.amount_unit = self.view.amount_unit_combo.currentText() self.model.solvent = self.view.solvent_input.text() for row in range(self.view.table.rowCount()): name_item = self.view.table.item(row, 0) percentage_item = self.view.table.item(row, 1) unit_widget = self.view.table.cellWidget(row, 2) conversion_item = self.view.table.item(row, 3) if not all([name_item, percentage_item, conversion_item]): continue name = name_item.text() percentage = float(percentage_item.text()) unit = unit_widget.currentText() conversion_factor = float(conversion_item.text()) reagent = Reagent(name, percentage, unit, conversion_factor) self.model.add_reagent(reagent) def _update_view_from_model(self): """Обновляет интерфейс данными из модели""" self.view.table.setRowCount(0) self.view.amount_input.setValue(self.model.total_amount) index = self.view.amount_unit_combo.findText(self.model.amount_unit) if index >= 0: self.view.amount_unit_combo.setCurrentIndex(index) self.view.solvent_input.setText(self.model.solvent) for reagent in self.model.reagents: row = self.view.table.rowCount() self.view.table.insertRow(row) self.view.table.setItem(row, 0, QTableWidgetItem(reagent.name)) self.view.table.setItem(row, 1, QTableWidgetItem(f"{reagent.percentage:.2f}")) unit_combo = QComboBox() unit_combo.addItems(["нг", "мкг", "мг", "г", "кг", "нл", "мкл", "мл", "л"]) unit_combo.setCurrentText(reagent.unit) self.view.table.setCellWidget(row, 2, unit_combo) self.view.table.setItem(row, 3, QTableWidgetItem(f"{reagent.conversion_factor:.2f}")) self.view.table.setItem(row, 4, QTableWidgetItem("")) def save_composition(self): """Сохраняет состав среды в JSON‑файл""" filename, _ = QFileDialog.getSaveFileName( self.view, "Сохранить состав среды", "", "JSON Files (*.json);;All Files (*)" ) if filename: if not filename.lower().endswith('.json'): filename += '.json' try: self._update_model_from_view() self.model.save_to_file(filename) QMessageBox.information(self.view, "Успех", "Состав среды успешно сохранён!") except Exception as e: self.view.show_error(f"Ошибка сохранения: {str(e)}") def load_composition(self): """Загружает состав среды из JSON‑файла""" filename, _ = QFileDialog.getOpenFileName( self.view, "Загрузить состав среды", "", "JSON Files (*.json);;All Files (*)" ) if filename: try: self.model.load_from_file(filename) self._update_view_from_model() # Исправлено: добавлены скобки () self.calculate() QMessageBox.information(self.view, "Успех", "Состав среды успешно загружен!") except Exception as e: self.view.show_error(f"Ошибка загрузки: {str(e)}")