144 lines
7.3 KiB
Python
144 lines
7.3 KiB
Python
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QTableWidgetItem, QComboBox
|
||
from PyQt5.QtCore import Qt
|
||
from PyQt5.QtGui import QColor
|
||
import json
|
||
from ..models.medium_model import MediumModel
|
||
from ..models.reagent import Reagent
|
||
from ..views.experiment_view import ExperimentDesignWindow
|
||
|
||
class MediumController:
|
||
def __init__(self, view):
|
||
self.model = MediumModel()
|
||
self.view = view
|
||
self.doe_window = None
|
||
self._connect_signals()
|
||
self._setup_initial_data()
|
||
|
||
def _connect_signals(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._perform_calculation)
|
||
self.view.save_btn.clicked.connect(self.save_composition)
|
||
self.view.load_btn.clicked.connect(self.load_composition)
|
||
self.view.to_doe_btn.clicked.connect(self.send_to_doe)
|
||
self.view.solvent_input.textChanged.connect(self.view.update_solvent_name)
|
||
|
||
def _setup_initial_data(self):
|
||
self.view.add_initial_rows()
|
||
|
||
def add_reagent_row(self):
|
||
self.view.add_new_row()
|
||
|
||
def remove_reagent_row(self):
|
||
self.view.remove_selected_row()
|
||
|
||
def _perform_calculation(self):
|
||
try:
|
||
self._update_model_from_view()
|
||
results, solvent_amount, solvent_percentage = self.model.calculate_amounts()
|
||
self.view.update_results(results)
|
||
self.view.update_solvent_result(solvent_amount, self.model.amount_unit)
|
||
self.view.update_solvent_percent(solvent_percentage)
|
||
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(1, 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)
|
||
dilution_item = self.view.table.item(row, 4)
|
||
if not all([name_item, percentage_item, conversion_item]):
|
||
continue
|
||
try:
|
||
name = name_item.text()
|
||
percentage = float(percentage_item.text())
|
||
unit = unit_widget.currentText() if unit_widget else "мг"
|
||
conversion_factor = float(conversion_item.text())
|
||
dilution_factor = float(dilution_item.text()) if dilution_item else 1.0
|
||
reagent = Reagent(name, percentage, unit, conversion_factor)
|
||
reagent.dilution_factor = dilution_factor
|
||
self.model.reagents.append(reagent)
|
||
except ValueError as e:
|
||
raise ValueError(f"Ошибка в строке {row + 1}: {str(e)}")
|
||
|
||
def send_to_doe(self):
|
||
"""Передаёт данные о реагентах в окно планирования эксперимента"""
|
||
reagents = self.view.get_reagents_data()
|
||
|
||
if len(reagents) == 0:
|
||
self.view.show_error("Нет реагентов для передачи в планировщик эксперимента!")
|
||
return
|
||
|
||
# Создаём или показываем существующее окно DoE
|
||
if self.doe_window is None:
|
||
self.doe_window = ExperimentDesignWindow()
|
||
|
||
# Передаём данные в окно DoE
|
||
self.doe_window.load_factors_from_reagents(reagents)
|
||
self.doe_window.show()
|
||
self.doe_window.raise_()
|
||
self.doe_window.activateWindow()
|
||
|
||
self.view.show_info(f"Передано {len(reagents)} реагентов в планировщик эксперимента\n"
|
||
f"Каждый реагент добавлен как фактор.\n"
|
||
f"Его концентрация (%) установлена как нулевой уровень.")
|
||
|
||
def save_composition(self):
|
||
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):
|
||
filename, _ = QFileDialog.getOpenFileName(self.view, "Загрузить состав среды", "", "JSON Files (*.json);;All Files (*)")
|
||
if filename:
|
||
try:
|
||
self.model.load_from_file(filename)
|
||
self._update_view_from_model()
|
||
QMessageBox.information(self.view, "Успех", "Состав среды успешно загружен")
|
||
except FileNotFoundError:
|
||
QMessageBox.critical(self.view, "Ошибка", f"Файл не найден: {filename}")
|
||
except json.JSONDecodeError as e:
|
||
QMessageBox.critical(self.view, "Ошибка", f"Неверный формат JSON-файла: {str(e)}")
|
||
except Exception as e:
|
||
QMessageBox.critical(self.view, "Ошибка", f"Ошибка при загрузке состава: {str(e)}")
|
||
|
||
def _update_view_from_model(self):
|
||
while self.view.table.rowCount() > 1:
|
||
self.view.table.removeRow(1)
|
||
if self.view.table.rowCount() == 0:
|
||
self.view.add_solvent_row()
|
||
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)
|
||
self.view.update_solvent_name()
|
||
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(f"{getattr(reagent, 'dilution_factor', 1.0):.3f}"))
|
||
self.view.table.setItem(row, 5, QTableWidgetItem(""))
|
||
self.view.clear_results()
|