Files
help_lab/src/controllers/medium_controller.py
T

144 lines
7.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()