Add All Folders
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
from PySide6.QtWidgets import (
|
||||
QMessageBox, QGraphicsRectItem, QGraphicsTextItem,
|
||||
QPushButton, QGraphicsProxyWidget, QTableWidget,
|
||||
QTableWidgetItem, QDialog, QVBoxLayout
|
||||
)
|
||||
from PySide6.QtGui import QBrush, QColor
|
||||
from pathlib import Path
|
||||
import napari
|
||||
import json
|
||||
from .port_item import PortItem # Import PortItem with type support
|
||||
|
||||
class NodeWidget(QGraphicsRectItem):
|
||||
def __init__(self, title: str, inputs: list[tuple[str, str]], outputs: list[tuple[str, str]]):
|
||||
"""
|
||||
inputs/outputs: list of (label, port_type)
|
||||
Example:
|
||||
inputs=[("Image", "Image"), ("Mask", "Mask")]
|
||||
outputs=[("Features", "Features")]
|
||||
"""
|
||||
super().__init__(0, 0, 160, 90)
|
||||
self.setBrush(QBrush(QColor("#e0e0e0")))
|
||||
self.title = QGraphicsTextItem(title, self)
|
||||
self.title.setPos(10, 5)
|
||||
|
||||
self.status_text = QGraphicsTextItem("", self)
|
||||
self.status_text.setPos(10, 40)
|
||||
|
||||
# Create input ports
|
||||
self.input_ports = []
|
||||
y_offset = 20
|
||||
for label, port_type in inputs:
|
||||
port = PortItem(label, port_type, is_input=True, parent=self)
|
||||
port.setPos(0, y_offset)
|
||||
self.input_ports.append(port)
|
||||
y_offset += 20
|
||||
|
||||
# Create output ports
|
||||
self.output_ports = []
|
||||
y_offset = 20
|
||||
for label, port_type in outputs:
|
||||
port = PortItem(label, port_type, is_input=False, parent=self)
|
||||
port.setPos(150, y_offset)
|
||||
self.output_ports.append(port)
|
||||
y_offset += 20
|
||||
|
||||
# Output Display Button
|
||||
self.btn_view = QPushButton("View Output")
|
||||
proxy = QGraphicsProxyWidget(self)
|
||||
proxy.setWidget(self.btn_view)
|
||||
proxy.setPos(10, 60)
|
||||
self.btn_view.clicked.connect(self.view_output)
|
||||
|
||||
def set_status(self, status: str):
|
||||
# Change node color and status text based on execution state
|
||||
if status == "running":
|
||||
self.setBrush(QBrush(QColor("yellow")))
|
||||
self.status_text.setPlainText("⏳ Running")
|
||||
elif status == "success":
|
||||
self.setBrush(QBrush(QColor("lightgreen")))
|
||||
self.status_text.setPlainText("✔ Success")
|
||||
elif status == "failed":
|
||||
self.setBrush(QBrush(QColor("red")))
|
||||
self.status_text.setPlainText("❌ Failed")
|
||||
else:
|
||||
self.setBrush(QBrush(QColor("#e0e0e0")))
|
||||
self.status_text.setPlainText("")
|
||||
|
||||
def view_output(self):
|
||||
node_type = self.title.toPlainText()
|
||||
|
||||
# Image Reader Or Image Filter → Processed Image
|
||||
if node_type in ["Image Reader", "Image Filter"]:
|
||||
file_path = Path("artifacts/processed_image.nii.gz")
|
||||
if file_path.exists():
|
||||
viewer = napari.Viewer()
|
||||
viewer.open(str(file_path))
|
||||
else:
|
||||
QMessageBox.warning(None, "Output not found", f"No output image for {node_type}")
|
||||
|
||||
# Mask Reader → Mask
|
||||
elif node_type == "Mask Reader":
|
||||
file_path = Path("artifacts/mask.nii.gz")
|
||||
if file_path.exists():
|
||||
viewer = napari.Viewer()
|
||||
viewer.open(str(file_path))
|
||||
else:
|
||||
QMessageBox.warning(None, "Output not found", "No mask file found")
|
||||
|
||||
# Image Registration → Registered image
|
||||
elif node_type == "Image Registration":
|
||||
file_path = Path("artifacts/registered_image.nii.gz")
|
||||
if file_path.exists():
|
||||
viewer = napari.Viewer()
|
||||
viewer.open(str(file_path))
|
||||
else:
|
||||
QMessageBox.warning(None, "Output not found", "No registered image found")
|
||||
|
||||
# Image Fusion → Composite Image
|
||||
elif node_type == "Image Fusion":
|
||||
file_path = Path("artifacts/fused_image.nii.gz")
|
||||
if file_path.exists():
|
||||
viewer = napari.Viewer()
|
||||
viewer.open(str(file_path))
|
||||
else:
|
||||
QMessageBox.warning(None, "Output not found", "No fused image found")
|
||||
|
||||
# Image Extraction Or PySERA Extract → Features table
|
||||
elif node_type in ["Image Extraction", "PySERA Extract"]:
|
||||
file_path = Path("artifacts/features.json")
|
||||
if file_path.exists():
|
||||
features = json.loads(file_path.read_text())
|
||||
dialog = QDialog()
|
||||
dialog.setWindowTitle("Radiomics Features")
|
||||
layout = QVBoxLayout(dialog)
|
||||
table = QTableWidget()
|
||||
table.setRowCount(len(features))
|
||||
table.setColumnCount(2)
|
||||
table.setHorizontalHeaderLabels(["Feature", "Value"])
|
||||
for i, (key, value) in enumerate(features.items()):
|
||||
table.setItem(i, 0, QTableWidgetItem(key))
|
||||
table.setItem(i, 1, QTableWidgetItem(str(value)))
|
||||
layout.addWidget(table)
|
||||
dialog.exec()
|
||||
else:
|
||||
QMessageBox.warning(None, "Output not found", "No features.json found")
|
||||
|
||||
# Writer → Final Output File
|
||||
elif node_type in ["Writer", "Image Writer"]:
|
||||
file_path = Path("artifacts/output.nii.gz")
|
||||
if file_path.exists():
|
||||
QMessageBox.information(None, "Writer Output", f"Output file saved: {file_path}")
|
||||
else:
|
||||
QMessageBox.warning(None, "Output not found", "No output file found")
|
||||
Reference in New Issue
Block a user