from PyQt5.QtWidgets import QGraphicsView, QWidget from panZoomGraphicsView import PanZoomGraphicsView from PyQt5.QtCore import Qt from PyQt5.QtGui import QMouseEvent, QWheelEvent from draggableCircleItem import DraggableCircleItem from typing import Optional # A specialized PanZoomGraphicsView for the circle editor (disk size calibration) class CircleEditorGraphicsView(PanZoomGraphicsView): def __init__(self, circle_editor_widget, parent: Optional[QWidget] = None): """ Constructor. """ super().__init__(parent) self._circle_editor_widget = circle_editor_widget def mousePressEvent(self, event: QMouseEvent): """ If the user clicks on the circle, we let the circle item handle the event. """ if event.button() == Qt.LeftButton: # Check if user clicked on the circle item clicked_item = self.itemAt(event.pos()) if clicked_item is not None: # climb up parent chain it = clicked_item while it is not None and not hasattr(it, "boundingRect"): it = it.parentItem() if isinstance(it, DraggableCircleItem): # Let normal item-dragging occur, no pan return QGraphicsView.mousePressEvent(self, event) super().mousePressEvent(event) def wheelEvent(self, event: QWheelEvent): """ If the user scrolls the mouse wheel over the circle, we change the circle """ pos_in_widget = event.pos() item_under = self.itemAt(pos_in_widget) if item_under is not None: it = item_under while it is not None and not hasattr(it, "boundingRect"): it = it.parentItem() if isinstance(it, DraggableCircleItem): delta = event.angleDelta().y() step = 1 if delta > 0 else -1 old_r = it.radius() new_r = max(1, old_r + step) it.set_radius(new_r) self._circle_editor_widget.update_slider_value(new_r) event.accept() return super().wheelEvent(event)