from PySide6.QtWidgets import QWidget, QLabel, QVBoxLayout, QFrame from PySide6.QtGui import QPainter, QColor, QPen from PySide6.QtCore import Qt, QRectF class PortWidget(QFrame): def __init__(self, name: str, dtype_repr: str, is_output: bool = False, parent=None): super().__init__(parent) self.name = name self.dtype_repr = dtype_repr self.is_output = is_output self.setFixedSize(14, 14) self.setToolTip(f"{name}\n{dtype_repr}") self.color = QColor(34,139,34) if is_output else QColor(70,130,180) self.setStyleSheet("background:transparent;") def paintEvent(self, event): p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) pen = QPen(Qt.black) p.setPen(pen) p.setBrush(self.color) r = QRectF(1,1,self.width()-2,self.height()-2) p.drawEllipse(r) class NodeWidget(QFrame): def __init__(self, title: str, parent=None): super().__init__(parent) self.setFrameShape(QFrame.Box) self.setStyleSheet("background:#f8f8f8;") self.title = QLabel(title) self.title.setStyleSheet("font-weight:bold;") self.layout = QVBoxLayout(self) self.layout.setContentsMargins(6,6,6,6) self.layout.addWidget(self.title) self.in_ports = [] self.out_ports = [] self.status_label = QLabel("status: pending") self.layout.addWidget(self.status_label) def add_in_port(self, port_widget: PortWidget): self.in_ports.append(port_widget) self.layout.addWidget(port_widget) def add_out_port(self, port_widget: PortWidget): self.out_ports.append(port_widget) self.layout.addWidget(port_widget) def set_status(self, status_text: str): self.status_label.setText(f"status: {status_text}")