""" Quality Results Panel Panel for displaying comprehensive quality grading results with breakdown. """ from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QSizePolicy, QProgressBar, QFrame) from PyQt5.QtCore import Qt from PyQt5.QtGui import QFont, QColor from ui.widgets.panel_header import PanelHeader class QualityResultsPanel(QWidget): """ Panel for displaying quality grading results. Shows final grade, grading breakdown with progress bars, and additional metrics. """ def __init__(self, parent=None): super().__init__(parent) self.current_grade = "B" self.overall_score = 78.5 self.grade_colors = { 'A': '#27ae60', 'B': '#f39c12', 'C': '#e74c3c' } self.init_ui() def init_ui(self): """Initialize the panel UI.""" # Set size policy 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 using the PanelHeader widget header = PanelHeader( title="Quality Grading Results", color="#27ae60" # Green for results/grading ) layout.addWidget(header) # Content area content = QWidget() content.setStyleSheet(""" background-color: #2c3e50; border: 1px solid #34495e; border-top: none; """) content_layout = QVBoxLayout(content) content_layout.setContentsMargins(10, 10, 10, 10) content_layout.setSpacing(12) # Final Grade Display self._create_grade_display(content_layout) # Separator self._add_separator(content_layout) # Grading Breakdown Section self._create_grading_breakdown(content_layout) # Separator self._add_separator(content_layout) # Overall Score Display self._create_overall_score(content_layout) # Separator self._add_separator(content_layout) # Additional Metrics Section self._create_additional_metrics(content_layout) layout.addWidget(content, 1) def _create_grade_display(self, parent_layout): """Create the final grade display widget.""" # Grade widget container grade_widget = QWidget() grade_widget.setFixedHeight(70) grade_widget.setStyleSheet(f""" QWidget {{ background-color: {self.grade_colors.get(self.current_grade, '#95a5a6')}; border-radius: 8px; border: 2px solid; }} """) grade_layout = QVBoxLayout(grade_widget) grade_layout.setContentsMargins(15, 10, 15, 10) grade_layout.setAlignment(Qt.AlignCenter) # Grade title grade_title = QLabel("FINAL QUALITY GRADE") grade_title.setFont(QFont("Arial", 10, QFont.Bold)) grade_title.setStyleSheet("color: white;") grade_title.setAlignment(Qt.AlignCenter) # Grade value (large) self.grade_value_label = QLabel(self.current_grade) self.grade_value_label.setFont(QFont("Arial", 32, QFont.Bold)) self.grade_value_label.setStyleSheet("color: white;") self.grade_value_label.setAlignment(Qt.AlignCenter) grade_layout.addWidget(grade_title) grade_layout.addWidget(self.grade_value_label) parent_layout.addWidget(grade_widget) def _create_grading_breakdown(self, parent_layout): """Create the grading breakdown section with progress bars.""" # Section label breakdown_label = QLabel("Grading Breakdown:") breakdown_label.setFont(QFont("Arial", 11, QFont.Bold)) breakdown_label.setStyleSheet("color: #ecf0f1;") parent_layout.addWidget(breakdown_label) # Sample grading metrics (including locule count) sample_metrics = [ {"name": "Size & Weight", "value": 90, "color": "#27ae60"}, {"name": "Shape Regularity", "value": 92, "color": "#27ae60"}, {"name": "Locule Count", "value": 95, "color": "#3498db"}, # High score for correct locule count {"name": "Surface Quality", "value": 70, "color": "#f39c12"}, {"name": "Color Uniformity", "value": 82, "color": "#27ae60"}, {"name": "Firmness (Thermal)", "value": 0, "color": "#7f8c8d"} ] self.metric_bars = {} for metric in sample_metrics: metric_widget = self._create_metric_bar( metric["name"], metric["value"], metric["color"] ) parent_layout.addWidget(metric_widget) def _create_metric_bar(self, name, value, color): """Create a single metric progress bar.""" # Container widget widget = QWidget() widget.setFixedHeight(25) layout = QHBoxLayout(widget) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(8) # Metric name label name_label = QLabel(name) name_label.setFont(QFont("Arial", 9)) name_label.setStyleSheet("color: #ecf0f1;") name_label.setFixedWidth(130) # Progress bar progress_bar = QProgressBar() progress_bar.setValue(value) progress_bar.setTextVisible(False) progress_bar.setFixedHeight(18) progress_bar.setStyleSheet(f""" QProgressBar {{ border: 1px solid #4a5f7a; border-radius: 3px; background-color: #34495e; text-align: center; }} QProgressBar::chunk {{ background-color: {color}; border-radius: 2px; }} """) # Value label (shows percentage or N/A) if value > 0: value_text = f"{value}%" value_color = color else: value_text = "N/A" value_color = "#7f8c8d" value_label = QLabel(value_text) value_label.setFont(QFont("Arial", 9, QFont.Bold)) value_label.setStyleSheet(f"color: {value_color};") value_label.setFixedWidth(35) value_label.setAlignment(Qt.AlignCenter) # Store reference for updates widget.progress_bar = progress_bar widget.value_label = value_label self.metric_bars[name] = widget layout.addWidget(name_label) layout.addWidget(progress_bar, 1) layout.addWidget(value_label) return widget def _create_overall_score(self, parent_layout): """Create the overall score display.""" # Overall score widget overall_widget = QWidget() overall_widget.setStyleSheet(""" QWidget { background-color: #34495e; border-radius: 5px; border: 1px solid #4a5f7a; } """) overall_layout = QHBoxLayout(overall_widget) overall_layout.setContentsMargins(15, 10, 15, 10) overall_layout.setSpacing(10) # Label overall_label = QLabel("Overall Quality Score:") overall_label.setFont(QFont("Arial", 11, QFont.Bold)) overall_label.setStyleSheet("color: #ecf0f1;") # Score value (large and prominent) self.overall_score_label = QLabel(f"{self.overall_score:.1f}%") self.overall_score_label.setFont(QFont("Arial", 18, QFont.Bold)) # Color code based on score ranges if self.overall_score >= 90: score_color = "#27ae60" # Green for excellent elif self.overall_score >= 75: score_color = "#f39c12" # Orange for good else: score_color = "#e74c3c" # Red for poor self.overall_score_label.setStyleSheet(f"color: {score_color};") overall_layout.addWidget(overall_label) overall_layout.addStretch() overall_layout.addWidget(self.overall_score_label) parent_layout.addWidget(overall_widget) def _create_additional_metrics(self, parent_layout): """Create additional metrics section.""" # Section label metrics_label = QLabel("Additional Metrics:") metrics_label.setFont(QFont("Arial", 10, QFont.Bold)) metrics_label.setStyleSheet("color: #ecf0f1;") parent_layout.addWidget(metrics_label) # Metrics container metrics_widget = QWidget() metrics_widget.setStyleSheet(""" QWidget { background-color: #34495e; border-radius: 3px; border: 1px solid #4a5f7a; } """) metrics_layout = QVBoxLayout(metrics_widget) metrics_layout.setContentsMargins(10, 8, 10, 8) metrics_layout.setSpacing(3) # Sample additional metrics sample_metrics = [ "• Estimated Weight: 185g", "• Diameter: 72mm (equatorial)", "• Aspect Ratio: 0.85 (oblate)", "• Surface Defect Coverage: 3.2%", "• Processing Time: 2.7s" ] for metric in sample_metrics: metric_label = QLabel(metric) metric_label.setFont(QFont("Arial", 8)) metric_label.setStyleSheet("color: #bdc3c7;") metrics_layout.addWidget(metric_label) # Model version info model_label = QLabel("Model: QualityNet v2.8") model_label.setFont(QFont("Arial", 8)) model_label.setStyleSheet("color: #7f8c8d;") metrics_layout.addWidget(model_label) parent_layout.addWidget(metrics_widget) def _add_separator(self, parent_layout): """Add a visual separator line.""" separator = QFrame() separator.setFrameShape(QFrame.HLine) separator.setStyleSheet("color: #4a5f7a;") separator.setFixedHeight(1) parent_layout.addWidget(separator) def update_grade(self, grade, score): """Update the grade and score display.""" self.current_grade = grade self.overall_score = score # Update grade display self.grade_value_label.setText(grade) # Update grade background color grade_color = self.grade_colors.get(grade, '#95a5a6') # Find the grade widget and update its color for i in range(self.layout().count()): child = self.layout().itemAt(i).widget() if hasattr(child, 'setStyleSheet'): # Grade display widget child.setStyleSheet(f""" QWidget {{ background-color: {grade_color}; border-radius: 8px; border: 2px solid; }} """) # Update overall score self.overall_score_label.setText(f"{score:.1f}%") # Update score color if score >= 90: score_color = "#27ae60" elif score >= 75: score_color = "#f39c12" else: score_color = "#e74c3c" self.overall_score_label.setStyleSheet(f"color: {score_color}; font-size: 18px; font-weight: bold;") def update_locule_count(self, count: int, confidence: float = 94.5): """Update the locule count metric in the grading breakdown.""" # Update the metric bar for locule count if "Locule Count" in self.metric_bars: widget = self.metric_bars["Locule Count"] # Calculate score based on locule count (4 is ideal for durian) # Perfect score (95%) for count=4, lower scores for other counts if count == 4: score = 95 elif count == 3 or count == 5: score = 85 elif count == 2 or count == 6: score = 70 else: score = 50 # Update progress bar widget.progress_bar.setValue(score) # Update value label (show both count and score) value_text = f"4/{count}" # Shows expected vs actual if count == 4: value_color = "#27ae60" # Green for correct count elif count >= 3 and count <= 5: value_color = "#f39c12" # Orange for acceptable range else: value_color = "#e74c3c" # Red for poor count widget.value_label.setText(value_text) widget.value_label.setStyleSheet(f"color: {value_color}; font-weight: bold;") def update_metric(self, metric_name, value): """Update a specific metric value.""" if metric_name in self.metric_bars: widget = self.metric_bars[metric_name] # Update progress bar widget.progress_bar.setValue(value) # Update value label if value > 0: value_text = f"{value}%" # Update color based on value if value >= 90: color = "#27ae60" elif value >= 75: color = "#f39c12" else: color = "#e74c3c" else: value_text = "N/A" color = "#7f8c8d" widget.value_label.setText(value_text) widget.value_label.setStyleSheet(f"color: {color}; font-weight: bold;")