缩放图像时的PyQt选择像素坐标

时间:2018-07-31 10:41:05

标签: python pyqt pyqt5

我正在尝试借助PyQt编写程序。用户应该能够浏览到图像,然后将图像加载到UI中,然后选择要进一步处理的图像(矩形)的一部分。用户也应该能够放大图像,以便能够更准确地选择他想要的部分。现在我有了以下代码

from PyQt5 import QtCore, QtGui, QtWidgets


class PhotoViewer(QtWidgets.QGraphicsView):
    photoClicked = QtCore.pyqtSignal(QtCore.QPoint)

    def __init__(self, parent):
        super().__init__(parent)
        self._zoom = 0
        self._empty = True
        self._scene = QtWidgets.QGraphicsScene(self)
        self._photo = QtWidgets.QGraphicsPixmapItem()
        self.rubberBand = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)
        self._origin = QtCore.QPoint()
        self._end = QtCore.QPoint()
        self._scene.addItem(self._photo)
        self.setScene(self._scene)
        self.setTransformationAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
        self._first = True
        # self.tempO = QtCore.QPointF()
        # self.tempE = QtCore.QPointF()

    def hasPhoto(self):
        return not self._empty

    def fitInView(self, scale=True):
        rect = QtCore.QRectF(self._photo.pixmap().rect())
        if not rect.isNull():
            self.setSceneRect(rect)
            if self.hasPhoto():
                unity = self.transform().mapRect(QtCore.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())
                self.scale(factor, factor)
            self._zoom = 0

    def setPhoto(self, pixmap=None):
        self._zoom = 0
        if pixmap and not pixmap.isNull():
            self._empty = False
            self._photo.setPixmap(pixmap)
        else:
            self._empty = True
            self.setDragMode(QtWidgets.QGraphicsView.NoDrag)
            self._photo.setPixmap(QtGui.QPixmap())
        self.fitInView()

    def wheelEvent(self, event):
        if self.hasPhoto():
            if event.angleDelta().y() > 0:
                factor = 1.25
                self._zoom += 1
            else:
                factor = 0.8
                self._zoom -= 1
            if self._zoom > 0:
                self.scale(factor, factor)
            elif self._zoom == 0:
                self.fitInView()
            else:
                self._zoom = 0

    def mousePressEvent(self, event):

        self._origin = QtCore.QPoint(event.pos())
        print(self._origin)
        self.rubberBand.setGeometry(QtCore.QRect(self._origin, 
                                                QtCore.QSize()))
        self.rubberBand.show()
        self._first=False
        # self.tempO=self._photo.mapFromItem(QtCore.QPointF(event.pos))

    def mouseMoveEvent(self, event):

        if  not self._first:
            self.rubberBand.setGeometry(QtCore.QRect(self._origin, 
                                    event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        self._end = QtCore.QPoint(event.pos())
        # self.tempE = self._photo.mapFromParent(QtCore.QPointF(event.pos))
        self._first=True
        print(self._origin.x(), self._origin.y())
        print(self._end.x(), self._end.y())
        # print(self.tempO.x(), self.tempO.y())
        # print(self.tempE.x(), self.tempE.y())


class Window(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.viewer = PhotoViewer(self)

        self.btnLoad = QtWidgets.QToolButton(self)
        self.btnLoad.setText('Load image')
        self.btnLoad.clicked.connect(self.loadImage)

        VBlayout = QtWidgets.QVBoxLayout(self)
        VBlayout.addWidget(self.viewer)
        HBlayout = QtWidgets.QHBoxLayout()
        HBlayout.setAlignment(QtCore.Qt.AlignLeft)
        HBlayout.addWidget(self.btnLoad)

        VBlayout.addLayout(HBlayout)

    def loadImage(self):
        filename,_ = QtWidgets.QFileDialog.getOpenFileName(self, 'single file', 
               QtCore.QDir.rootPath(),"images (*.png *.jpg)")
        self.viewer.setPhoto(QtGui.QPixmap(filename))

    def pixInfo(self):
        self.viewer.toggleDragMode()



if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 300, 800, 600)
    window.show()
    sys.exit(app.exec_())

大多数代码来自here。问题是给定的坐标位于PhotoViewer的对象的坐标系中,但我希望它位于_photo字段的坐标系中。坐标系统可能应该使用mapFromParent方法进行更改。我尝试过,但是程序崩溃了(我的尝试在上面的代码中被注释掉了)

那么这里的解决方案是什么?

先谢谢您

0 个答案:

没有答案