Files
help_lab/controller.py
T

193 lines
8.7 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 QMessageBox, QFileDialog, QTableWidgetItem, QComboBox, QLineEdit, QDoubleSpinBox
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor
from model import Model
from view import MediumCalculatorWindow
import json
from reagent import Reagent
class Controller:
def __init__(self):
self.model = Model()
self.view = MediumCalculatorWindow()
self._connect_signals()
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.solvent_input.textChanged.connect(self.view.update_solvent_name)
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()
# Заполняем реагенты из таблицы (начиная с 1 строки, пропуская растворитель)
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_widget = self.view.table.cellWidget(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())
# Получаем коэффициент разбавления (поддерживаем QDoubleSpinBox и QLineEdit)
dilution_factor = 1.0
if dilution_widget:
if isinstance(dilution_widget, QDoubleSpinBox):
dilution_factor = dilution_widget.value()
elif isinstance(dilution_widget, QLineEdit):
try:
dilution_factor = float(dilution_widget.text())
except ValueError:
dilution_factor = 1.0
# Добавляем реагент в модель
self.model.add_reagent(name, percentage, unit, conversion_factor, dilution_factor)
except ValueError as e:
raise ValueError(f"Ошибка в строке {row + 1}: {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}"))
# Единица - QComboBox
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()
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()
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)}"
)