我正在尝试借助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
方法进行更改。我尝试过,但是程序崩溃了(我的尝试在上面的代码中被注释掉了)
那么这里的解决方案是什么?
先谢谢您