small rewrite to impose dry principles
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
"""
|
||||
Filename: participant.py
|
||||
Description: Participant analysis window for FLARES
|
||||
|
||||
Author: Tyler de Zeeuw
|
||||
License: GPL-3.0
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
from PySide6.QtWidgets import QGridLayout, QHBoxLayout, QMessageBox, QPushButton, QScrollArea, QWidget, QVBoxLayout, QLabel
|
||||
from PySide6.QtCore import Qt, QSize
|
||||
from PySide6.QtGui import QPixmap
|
||||
|
||||
from src.shared.flaresbasewidget import ClickableLabel, FlaresBaseWidget
|
||||
from src.shared.shareddata import APP_NAME
|
||||
|
||||
|
||||
class ParticipantImageViewerWidget(FlaresBaseWidget):
|
||||
def __init__(self, haemo_dict, fig_bytes_dict):
|
||||
super().__init__("ParticipantImage")
|
||||
self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
|
||||
self.setWindowTitle(f"Participant Viewer - {APP_NAME.upper()}")
|
||||
self.haemo_dict = haemo_dict
|
||||
self.fig_bytes_dict = fig_bytes_dict
|
||||
|
||||
# Create mappings: file_path -> participant label and dropdown display text
|
||||
self.participant_map = {} # file_path -> "Participant 1"
|
||||
self.participant_dropdown_items = [] # "Participant 1 (filename)"
|
||||
|
||||
for i, file_path in enumerate(self.haemo_dict.keys(), start=1):
|
||||
short_label = f"Participant {i}"
|
||||
display_label = f"{short_label} ({os.path.basename(file_path)})"
|
||||
self.participant_map[file_path] = short_label
|
||||
self.participant_dropdown_items.append(display_label)
|
||||
|
||||
self.layout = QVBoxLayout(self)
|
||||
self.top_bar = QHBoxLayout()
|
||||
self.layout.addLayout(self.top_bar)
|
||||
|
||||
self.participant_dropdown = self._create_multiselect_dropdown(self.participant_dropdown_items)
|
||||
self.participant_dropdown.currentIndexChanged.connect(self.update_participant_dropdown_label)
|
||||
|
||||
first_fig_dict = next(iter(self.fig_bytes_dict.values()))
|
||||
image_label_items = list(first_fig_dict.keys())
|
||||
|
||||
self.image_index_dropdown = self._create_multiselect_dropdown(image_label_items)
|
||||
self.image_index_dropdown.currentIndexChanged.connect(self.update_image_index_dropdown_label)
|
||||
|
||||
self.submit_button = QPushButton("Submit")
|
||||
self.submit_button.clicked.connect(self.show_selected_images)
|
||||
|
||||
self.top_bar.addWidget(QLabel("Participants:"))
|
||||
self.top_bar.addWidget(self.participant_dropdown)
|
||||
self.top_bar.addWidget(QLabel("Image Indexes:"))
|
||||
self.top_bar.addWidget(self.image_index_dropdown)
|
||||
self.top_bar.addWidget(self.submit_button)
|
||||
|
||||
self.scroll = QScrollArea()
|
||||
self.scroll.setWidgetResizable(True)
|
||||
self.scroll_content = QWidget()
|
||||
self.grid_layout = QGridLayout(self.scroll_content)
|
||||
self.scroll.setWidget(self.scroll_content)
|
||||
self.layout.addWidget(self.scroll)
|
||||
|
||||
self.thumb_size = QSize(280, 180)
|
||||
|
||||
self.save_button = QPushButton("Save Displayed Images")
|
||||
self.save_button.clicked.connect(self.save_displayed_images)
|
||||
self.top_bar.addWidget(self.save_button)
|
||||
|
||||
self.showMaximized()
|
||||
|
||||
|
||||
|
||||
def show_selected_images(self):
|
||||
# Clear previous images
|
||||
while self.grid_layout.count():
|
||||
item = self.grid_layout.takeAt(0)
|
||||
widget = item.widget()
|
||||
if widget:
|
||||
widget.deleteLater()
|
||||
|
||||
selected_display_names = self._get_checked_items(self.participant_dropdown)
|
||||
# Map from display names back to file paths
|
||||
selected_file_paths = []
|
||||
for display_name in selected_display_names:
|
||||
# Find file_path by matching display name
|
||||
for fp, short_label in self.participant_map.items():
|
||||
expected_display = f"{short_label} ({os.path.basename(fp)})"
|
||||
if display_name == expected_display:
|
||||
selected_file_paths.append(fp)
|
||||
break
|
||||
|
||||
selected_labels = self._get_checked_items(self.image_index_dropdown)
|
||||
|
||||
row, col = 0, 0
|
||||
for file_path in selected_file_paths:
|
||||
fig_list = self.fig_bytes_dict.get(file_path, [])
|
||||
participant_label = self.participant_map[file_path]
|
||||
for label in selected_labels:
|
||||
fig_bytes = fig_list.get(label)
|
||||
if not fig_bytes:
|
||||
continue
|
||||
|
||||
full_pixmap = QPixmap()
|
||||
full_pixmap.loadFromData(fig_bytes)
|
||||
|
||||
thumbnail_pixmap = full_pixmap.scaled(
|
||||
self.thumb_size,
|
||||
Qt.AspectRatioMode.KeepAspectRatio,
|
||||
Qt.TransformationMode.SmoothTransformation
|
||||
)
|
||||
|
||||
container = QWidget()
|
||||
hlayout = QHBoxLayout(container)
|
||||
hlayout.setContentsMargins(0, 0, 0, 0)
|
||||
hlayout.setSpacing(0)
|
||||
hlayout.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
image_label = ClickableLabel(full_pixmap, thumbnail_pixmap)
|
||||
image_label.setToolTip(f"{participant_label}\n{label}")
|
||||
hlayout.addWidget(image_label)
|
||||
|
||||
self.grid_layout.addWidget(container, row, col)
|
||||
|
||||
col += 1
|
||||
if col >= 6:
|
||||
col = 0
|
||||
row += 1
|
||||
|
||||
# Update dropdown labels after display
|
||||
self.update_participant_dropdown_label()
|
||||
self.update_image_index_dropdown_label()
|
||||
|
||||
|
||||
def save_displayed_images(self):
|
||||
# Ensure the folder exists
|
||||
save_dir = Path("individual_images")
|
||||
save_dir.mkdir(exist_ok=True)
|
||||
|
||||
selected_display_names = self._get_checked_items(self.participant_dropdown)
|
||||
selected_image_labels = self._get_checked_items(self.image_index_dropdown)
|
||||
|
||||
for display_name in selected_display_names:
|
||||
# Match display name to file path
|
||||
for file_path, short_label in self.participant_map.items():
|
||||
expected_display = f"{short_label} ({os.path.basename(file_path)})"
|
||||
if display_name == expected_display:
|
||||
fig_dict = self.fig_bytes_dict.get(file_path, {})
|
||||
for label in selected_image_labels:
|
||||
if label not in fig_dict:
|
||||
continue
|
||||
fig_bytes = fig_dict[label]
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"{os.path.basename(file_path)}_{label}_{timestamp}.png"
|
||||
output_path = save_dir / filename
|
||||
with open(output_path, "wb") as f:
|
||||
f.write(fig_bytes)
|
||||
break # file_path matched; stop loop
|
||||
|
||||
QMessageBox.information(self, "Save Complete", f"Images saved to {save_dir.resolve()}")
|
||||
Reference in New Issue
Block a user