| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- """
- 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;")
|