143 lines
6.4 KiB
Python
143 lines
6.4 KiB
Python
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)}")
|