| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- """
- Visualization Widgets
- Reusable components for displaying analysis visualizations with click-to-enlarge functionality.
- """
- from typing import Optional, Callable
- from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QFrame
- from PyQt5.QtCore import Qt
- from PyQt5.QtGui import QPixmap, QFont, QCursor
- from ui.dialogs.image_preview_dialog import ImagePreviewDialog
- class ClickableImageWidget(QFrame):
- """
- A frame widget displaying an image that opens a preview dialog when clicked.
-
- Features:
- - Displays scaled image with aspect ratio preserved
- - Click to open full-size preview dialog
- - Visual indicator (cursor change, optional hover effect)
- - Configurable maximum dimensions
- """
-
- def __init__(self, pixmap: QPixmap, title: str, max_width: int = 500, parent: QWidget = None):
- """
- Initialize the clickable image widget.
-
- Args:
- pixmap: QPixmap to display
- title: Title for the preview dialog
- max_width: Maximum width in pixels for the scaled display image
- parent: Parent widget
- """
- super().__init__(parent)
- self.original_pixmap = pixmap # Store original for preview dialog
- self.title = title
- self.max_width = max_width
-
- # Setup widget styling
- self.setFrameStyle(QFrame.Box)
- self.setStyleSheet("background-color: white; border: 1px solid #bdc3c7;")
-
- # Create layout
- layout = QVBoxLayout(self)
- layout.setAlignment(Qt.AlignCenter)
-
- # Title label
- title_label = QLabel(f"<b>{title}</b>")
- title_label.setFont(QFont("Arial", 12))
- layout.addWidget(title_label)
-
- # Image label
- self.image_label = QLabel()
- self.image_label.setAlignment(Qt.AlignCenter)
- self.image_label.setCursor(Qt.PointingHandCursor)
-
- # Scale pixmap for display
- scaled_pixmap = self._scale_pixmap(pixmap, max_width)
- self.image_label.setPixmap(scaled_pixmap)
- self.image_label.setFixedSize(scaled_pixmap.width(), scaled_pixmap.height())
-
- # Connect click event
- self.image_label.mousePressEvent = self._on_image_clicked
-
- layout.addWidget(self.image_label, alignment=Qt.AlignCenter)
- layout.addStretch()
-
- def _scale_pixmap(self, pixmap: QPixmap, max_width: int) -> QPixmap:
- """Scale pixmap to fit max_width while preserving aspect ratio."""
- if pixmap.width() > max_width:
- return pixmap.scaledToWidth(max_width, Qt.SmoothTransformation)
- return pixmap
-
- def _on_image_clicked(self, event):
- """Handle image click to show preview dialog."""
- dialog = ImagePreviewDialog(self.original_pixmap, title=self.title, parent=self)
- dialog.exec_()
- class VisualizationPanel(QFrame):
- """
- A panel for displaying a single analysis visualization with metadata.
-
- Features:
- - Title and description
- - Clickable image
- - Optional metadata display
- """
-
- def __init__(self, title: str, description: str = "", parent: QWidget = None):
- """
- Initialize the visualization panel.
-
- Args:
- title: Panel title
- description: Optional description text
- parent: Parent widget
- """
- super().__init__(parent)
- self.setFrameStyle(QFrame.Box)
- self.setStyleSheet("background-color: white; border: 1px solid #bdc3c7;")
-
- layout = QVBoxLayout(self)
- layout.setAlignment(Qt.AlignCenter)
-
- # Title
- title_label = QLabel(f"<b>{title}</b>")
- title_label.setFont(QFont("Arial", 12))
- layout.addWidget(title_label)
-
- # Description (if provided)
- if description:
- desc_label = QLabel(description)
- desc_label.setStyleSheet("color: #7f8c8d; font-size: 10px;")
- layout.addWidget(desc_label)
-
- # Store reference to layout for adding image label later
- self.layout_ref = layout
-
- def add_image(self, pixmap: QPixmap, max_width: int = 500):
- """Add an image to the visualization panel."""
- # Scale image
- if pixmap.width() > max_width:
- scaled_pixmap = pixmap.scaledToWidth(max_width, Qt.SmoothTransformation)
- else:
- scaled_pixmap = pixmap
-
- # Create clickable image label
- image_label = QLabel()
- image_label.setPixmap(scaled_pixmap)
- image_label.setFixedSize(scaled_pixmap.width(), scaled_pixmap.height())
- image_label.setAlignment(Qt.AlignCenter)
- image_label.setCursor(Qt.PointingHandCursor)
-
- # Store pixmaps for click handler
- image_label.original_pixmap = pixmap
- image_label.title = self.layout_ref.itemAt(0).widget().text() if self.layout_ref.count() > 0 else "Image"
-
- # Add click handler
- def on_click(event):
- dialog = ImagePreviewDialog(image_label.original_pixmap, title=image_label.title, parent=self)
- dialog.exec_()
-
- image_label.mousePressEvent = on_click
-
- # Add to layout
- self.layout_ref.addWidget(image_label, alignment=Qt.AlignCenter)
- self.layout_ref.addStretch()
|