SimpleCalc Full Code Example¶
import logging
from utils.MetaModel import MetaModel
from utils.LogDecorator import log
class SimpleCalcModel(MetaModel):
"""
Simple calculator model to store and compute values.
Supports addition (+) and subtraction (-) operations.
"""
logger = logging.getLogger(__name__)
@log(logger=logger)
def _init(self):
self.results = []
@log(logger=logger)
def compute(self, left, operator, right):
if len(self.results) >= 5:
return None
if operator == "+":
result = left + right
elif operator == "-":
result = left - right
else:
return None
self.results.append(result)
return result
@log(logger=logger)
def get_results(self):
return self.results
@log(logger=logger)
def reset(self):
self.results = []
from PySide6.QtWidgets import (
QVBoxLayout, QHBoxLayout, QLineEdit, QComboBox, QPushButton, QLabel
)
from PySide6.QtCore import Signal
from utils.MetaView import MetaView
from utils.LogDecorator import log
class SimpleCalcView(MetaView):
calculate_operation = Signal(float, str, float)
request_plot = Signal()
request_reset = Signal()
def _init(self):
self.result_labels = []
self.result_list = []
self.limit_warning_label = None
def _set_control_area(self, layout):
self.main_layout = QVBoxLayout()
layout.addLayout(self.main_layout)
input_layout = QHBoxLayout()
self.left_input = QLineEdit()
self.left_input.setPlaceholderText("Value")
self.operator_box = QComboBox()
self.operator_box.addItems(["+", "-"])
self.right_input = QLineEdit()
self.right_input.setPlaceholderText("Value")
self.calculate_button = QPushButton("Add Calculation")
self.calculate_button.clicked.connect(self._on_add_calculation)
input_layout.addWidget(self.left_input)
input_layout.addWidget(self.operator_box)
input_layout.addWidget(self.right_input)
input_layout.addWidget(self.calculate_button)
self.main_layout.addLayout(input_layout)
results_container = QHBoxLayout()
results_container.setContentsMargins(0, 0, 0, 0)
self.result_display_container = QHBoxLayout()
self.result_display_container.setContentsMargins(0, 0, 0, 0)
self.result_display_container.setSpacing(5)
results_container.addWidget(QLabel("Results:"))
results_container.addLayout(self.result_display_container)
self.limit_warning_label = QLabel("")
self.limit_warning_label.setStyleSheet("color: red; font-style: italic;")
results_container.addWidget(self.limit_warning_label)
self.main_layout.addLayout(results_container)
btn_layout = QHBoxLayout()
self.plot_button = QPushButton("Plot")
self.plot_button.clicked.connect(self.request_plot.emit)
self.reset_button = QPushButton("Reset")
self.reset_button.clicked.connect(self._on_reset)
btn_layout.addWidget(self.plot_button)
btn_layout.addWidget(self.reset_button)
self.main_layout.addLayout(btn_layout)
def _on_add_calculation(self):
try:
left = float(self.left_input.text())
right = float(self.right_input.text())
operator = self.operator_box.currentText()
self.calculate_operation.emit(left, operator, right)
except ValueError:
return
def add_result(self, result):
if len(self.result_labels) >= 5:
self.limit_warning_label.setText("You have reached the limit! Reset to start again...")
return
label = QLabel(f"[ {result} ]")
self.result_labels.append(label)
self.result_display_container.addWidget(label)
if len(self.result_labels) == 5:
self.limit_warning_label.setText("You have reached the limit! Reset to start...")
def _on_reset(self):
self._reset_actions()
self.request_reset.emit()
def _reset_actions(self):
self.left_input.clear()
self.right_input.clear()
self.operator_box.setCurrentIndex(0)
for label in self.result_labels:
self.result_display_container.removeWidget(label)
label.deleteLater()
self.result_labels = []
self.result_list = []
try:
self.figure.clear()
self.canvas.draw()
except AttributeError:
pass
self.limit_warning_label.setText("")
def update_plot_data(self, results):
self.result_list = results
def update_plot(self):
self.figure.clear()
ax = self.figure.add_subplot(111)
ax.plot(self.result_list, marker='o')
ax.set_title("Results Over Time")
ax.set_xlabel("Step")
ax.set_ylabel("Result")
self.canvas.draw()
def update_available_plugins(self, _):
pass
import logging
from utils.MetaController import MetaController
from utils.LogDecorator import log
from plugins.analysistabs.SimpleCalcView import SimpleCalcView
from plugins.analysistabs.SimpleCalcModel import SimpleCalcModel
class SimpleCalcController(MetaController):
"""
Controller for the SimpleCalc plugin.
Connects user input from the view to calculation logic in the model.
"""
logger = logging.getLogger(__name__)
@log(logger=logger)
def _init(self):
self.view = SimpleCalcView()
self.model = SimpleCalcModel()
@log(logger=logger)
def _setup_connections(self):
self.view.calculate_operation.connect(self.handle_add)
self.view.request_plot.connect(self.handle_plot)
self.view.request_reset.connect(self.handle_reset)
@log(logger=logger)
def handle_add(self, left, operator, right):
result = self.model.compute(left, operator, right)
if result is not None:
self.view.add_result(result)
@log(logger=logger)
def handle_plot(self):
results = self.model.get_results()
self.view.update_plot_data(results)
self.view.update_plot()
@log(logger=logger)
def handle_reset(self):
self.model.reset()
Pro Tip
You may have noticed the @log(logger=logger) tags above some functions.
This is Poriscope’s way of automatically keeping track of what happens in your plugin — like when a function starts, ends, or runs into a problem.
It helps with troubleshooting and understanding how everything runs behind the scenes — without needing to write a lot of extra code.
If you want to log your own messages inside the function (like notes or warnings), you can still do that using lines like self.logger.info("Your message here").
For more details, see Logging.