feat: инициализация проекта калькулятора питательных сред
This commit is contained in:
+142
@@ -0,0 +1,142 @@
|
||||
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)}")
|
||||
Reference in New Issue
Block a user