在 QGraphicsView 中启用平移/缩放

问题描述 投票:0回答:1

我正在使用 Python 和 QtDesigner 来显示带有叠加层的相机图像。 我的主窗口可以访问相机设置,并相应地触发相机。它通过 pyQtSlot 将每个图像发送到 QGraphicsView。

如何在此 QGraphicView 中启用缩放功能?

我已阅读答案如何在 QGraphicsView 中启用平移和缩放 它对于冻结的图片效果很好,但是当我发送下一张图像时,缩放会重置。

这是我的工作代码(因此我没有尝试实现缩放):

from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QWidget, QGraphicsPixmapItem
from PyQt5.QtGui import QImage, QPainter, QPixmap
from PyQt5.QtCore import QRectF, pyqtSlot, Qt

class Display(QGraphicsView):
    def __init__(self, parent: QWidget = None):
        super().__init__(parent)
        self._empty = True
        self.image_qt = QImage()
        self._scene = QGraphicsScene()
        self.pic = QGraphicsPixmapItem()
        self._scene.addItem(self.pic)
        self.setScene(self._scene)
        self.setAlignment(Qt.AlignCenter)

    def hasPicture(self):
        return not self._empty

    @pyqtSlot(QImage)
    def on_image_received(self, image: QImage, scale: float, x_offset: int, y_offset: int):
        # Scale the overlay, Adjust the position
        # self.image_qt = set_calque(image, scale, x_offset, y_offset)
        # not useful for a minimal example, so skip the overlay part:
        self.image_qt = image

        # Image size
        image_width = self.image_qt.width()
        image_height = self.image_qt.height()

        # Return if we don't have an image yet
        if image_width == 0 or image_height == 0:
            return

        self._empty = False
        self.pic.setPixmap(QPixmap.fromImage(self.image_qt))
        self.fitInView(QRectF(0, 0, image_width, image_height), Qt.KeepAspectRatio)
        self.update()
python pyqt5 qgraphicsview qgraphicsscene
1个回答
0
投票

经过几次尝试,我几乎可以正常工作了:我认为缩放没有很好地集中在鼠标位置上,但我不明白为什么。

from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QWidget, QGraphicsPixmapItem
from PyQt5.QtGui import QImage, QPainter, QPixmap
from PyQt5.QtCore import QRectF, pyqtSlot, Qt, QPoint


class Display(QGraphicsView):
    def __init__(self, parent: QWidget = None):
        super().__init__(parent)
        self._zoom = 1
        self._pt = QPoint()
        self._empty = True
        self.image_qt = QImage()
        self._scene = QGraphicsScene()
        self.pic = QGraphicsPixmapItem()
        self._scene.addItem(self.pic)
        self.setScene(self._scene)
        self.setAlignment(Qt.AlignCenter)

    def hasPicture(self):
        return not self._empty

    def wheelEvent(self, event):
        # self.pt = self.mapToScene(event.pos()).toPoint()
        self._pt = event.pos()
        if self.hasPicture():
            if event.angleDelta().y() > 0:
                factor = 1.2
                self._zoom *= factor
            else:
                factor = 0.8
                self._zoom *= factor
            if self._zoom > 0:
                self.scale(factor, factor)

    @pyqtSlot(QImage)
    def on_image_received(self, image: QImage, scale: float, x_offset: int, y_offset: int):
        # overlay the image. Scale the overlay, Adjust its position
        self.image_qt = set_calque(image, scale, x_offset, y_offset)

        # Image size
        image_width = self.image_qt.width()
        image_height = self.image_qt.height()

        # Return if we don't have an image yet
        if image_width == 0 or image_height == 0:
            return

        self._empty = False
        self.setDragMode(QGraphicsView.ScrollHandDrag)
        self.pic.setPixmap(QPixmap.fromImage(self.image_qt))
        self.fitInView()
        self.update()

    def fitInView(self, scale=True):
        rect = QRectF(self.pic.pixmap().rect())
        if not rect.isNull():
            if not self._pt.isNull() and self._zoom > 1:
                rect.moveCenter(self._pt)
            self.setSceneRect(rect)
            if self.hasPicture():
                unity = self.transform().mapRect(QRectF(0, 0, 1, 1))
                self.scale(1 / unity.width(), 1 / unity.height())
                viewrect = self.viewport().rect()
                scenerect = self.transform().mapRect(rect)
                factor = min(viewrect.width() / scenerect.width(),
                             viewrect.height() / scenerect.height())
                factor *= self._zoom
                self.scale(factor, factor)
© www.soinside.com 2019 - 2024. All rights reserved.