""" Ripeness Results Panel Panel for displaying ripeness classification results with confidence bars. """ from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QProgressBar, QSizePolicy from PyQt5.QtCore import Qt from PyQt5.QtGui import QFont from ui.widgets.panel_header import PanelHeader from ui.widgets.confidence_bar import ConfidenceBar class RipenessResultsPanel(QWidget): """ Panel for displaying ripeness analysis results. """ def __init__(self, parent=None): super().__init__(parent) self.init_ui() def init_ui(self): """Initialize the panel UI.""" # Set size policy to expand equally self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) # Main panel container with card styling self.setStyleSheet(""" QWidget { background-color: white; border: 1px solid #ddd; } """) # Header header = QWidget() header.setFixedHeight(25) header.setStyleSheet("background-color: #27ae60;") header_layout = QHBoxLayout(header) header_layout.setContentsMargins(10, 0, 0, 0) title = QLabel("Ripeness Analysis Results") title.setStyleSheet("color: white; font-weight: bold; font-size: 16px;") header_layout.addWidget(title) # Current Classification classification_label = QLabel("Current Classification:") classification_label.setStyleSheet("font-weight: bold; font-size: 12px; margin: 8px 10px 5px 10px; color: #2c3e50;") classification_frame = QWidget() classification_frame.setStyleSheet("background-color: #95a5a6;") classification_frame.setMinimumHeight(45) classification_layout = QVBoxLayout(classification_frame) classification_layout.setAlignment(Qt.AlignCenter) classification_layout.setContentsMargins(5, 5, 5, 5) self.class_display = QLabel("—") self.class_display.setAlignment(Qt.AlignCenter) self.class_display.setStyleSheet("color: white; font-weight: bold; font-size: 18px;") classification_layout.addWidget(self.class_display) # Confidence Scores confidence_label = QLabel("Confidence Scores:") confidence_label.setStyleSheet("font-weight: bold; font-size: 11px; margin: 8px 10px 5px 10px; color: #2c3e50;") # Create progress bars for each category categories = [ ("Unripe", 0, "#95a5a6"), ("Ripe", 0, "#27ae60"), ("Overripe", 0, "#e74c3c") ] confidence_layout = QVBoxLayout() confidence_layout.setSpacing(4) self.confidence_bars = {} for name, value, color in categories: category_frame = QWidget() category_layout = QHBoxLayout(category_frame) category_layout.setContentsMargins(10, 0, 10, 0) category_layout.setSpacing(8) name_label = QLabel(f"{name}:") name_label.setFixedWidth(60) name_label.setStyleSheet("font-size: 10px; color: #2c3e50;") progress = QProgressBar() progress.setRange(0, 100) progress.setValue(int(value)) progress.setTextVisible(False) progress.setStyleSheet(f""" QProgressBar {{ background-color: #ecf0f1; border: 1px solid #bdc3c7; border-radius: 0px; height: 15px; }} QProgressBar::chunk {{ background-color: {color}; }} """) value_label = QLabel(f"{value}%") value_label.setFixedWidth(45) value_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter) value_label.setStyleSheet("font-size: 12px; color: #2c3e50;") category_layout.addWidget(name_label) category_layout.addWidget(progress) category_layout.addWidget(value_label) confidence_layout.addWidget(category_frame) self.confidence_bars[name] = (progress, value_label) # Processing time self.info_label = QLabel("") self.info_label.setStyleSheet("color: #7f8c8d; font-size: 12px; margin: 8px 10px 5px 10px;") layout.addWidget(header) layout.addWidget(classification_label) layout.addWidget(classification_frame) layout.addWidget(confidence_label) layout.addLayout(confidence_layout) layout.addWidget(self.info_label) layout.addStretch() def update_results(self, classification: str, probabilities: dict, processing_time: float = 0, model_version: str = "RipeNet v3.2"): """ Update the results display. Args: classification: Predicted class name probabilities: Dictionary of class probabilities (0-1) processing_time: Processing time in seconds model_version: Model version string """ # Update classification display self.class_display.setText(classification.upper()) # Set color based on classification class_colors = { "Unripe": "#95a5a6", "Ripe": "#27ae60", "Overripe": "#e74c3c" } bg_color = class_colors.get(classification, "#95a5a6") self.class_display.parent().setStyleSheet(f"background-color: {bg_color};") self.class_display.setStyleSheet(""" color: white; font-weight: bold; font-size: 18px; """) # Update confidence bars for class_name, (progress_bar, value_label) in self.confidence_bars.items(): prob = probabilities.get(class_name, 0) percentage = prob * 100 # Update progress bar progress_bar.setValue(int(percentage)) # Update value label value_label.setText(f"{percentage:.1f}%") # Highlight primary class if class_name == classification: value_label.setStyleSheet("font-size: 12px; font-weight: bold; color: #2c3e50;") else: value_label.setStyleSheet("font-size: 12px; color: #2c3e50;") # Update info label self.info_label.setText( f"Processing Time: {processing_time:.2f}s | Model: {model_version}" ) def clear_results(self): """Clear all results.""" self.class_display.setText("—") self.class_display.setStyleSheet(""" color: white; font-weight: bold; font-size: 18px; """) for progress_bar, value_label in self.confidence_bars.values(): progress_bar.setValue(0) value_label.setText("0%") value_label.setStyleSheet("font-size: 12px; color: #2c3e50;") self.info_label.setText("")