from PyQt6.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsPixmapItem from PyQt6.QtGui import QPixmap, QWheelEvent, QPainter, QImage from PyQt6.QtCore import Qt class ImageCanvas(QGraphicsView): _pixmapItem: QGraphicsPixmapItem empty = True def __init__(self): super().__init__() self.scene = QGraphicsScene() self.setScene(self.scene) self._pixmapItem = QGraphicsPixmapItem() self.scene.addItem(self._pixmapItem) self.setRenderHints(QPainter.RenderHint.Antialiasing | QPainter.RenderHint.SmoothPixmapTransform) self.setDragMode(self.DragMode.ScrollHandDrag) self.setTransformationAnchor(self.ViewportAnchor.AnchorUnderMouse) def wheelEvent(self, event: QWheelEvent): zoom_in_factor = 1.25 zoom_out_factor = 1.0 / zoom_in_factor if event.angleDelta().y() > 0: self.scale(zoom_in_factor, zoom_in_factor) else: self.scale(zoom_out_factor, zoom_out_factor) def updatePixmap(self, image: QImage): pixmap = QPixmap.fromImage(image) self._pixmapItem.setPixmap(pixmap) if self.empty: self.reset() self.empty = False def clear(self): self.scene.removeItem(self._pixmapItem) self._pixmapItem = QGraphicsPixmapItem() self.scene.addItem(self._pixmapItem) self.empty = True def reset(self): self.resetTransform() # Reset the zoom level to default self.fitInView(self._pixmapItem, Qt.AspectRatioMode.KeepAspectRatio) # Fit the image to the view