gpt4 book ai didi

python - 如何在 QGraphicsScene 中找到 QGraphicsPixmapItem 的像素边界

转载 作者:太空宇宙 更新时间:2023-11-03 20:03:04 24 4
gpt4 key购买 nike

我有一个 png 作为 QGraphicsPixmapItem 读入我的 python 程序。然后将此 QGraphicsPixmapItem 添加到 QGraphicsScene 中进行显示。在显示中,用户可以放大和平移图像。这按预期工作。

我的问题是这样的:如何确定缩放和平移后 QGraphicsScene 角落的 PNG 像素值

有内置的 PyQt 方法吗?

我当前的代码:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog


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

def __init__(self, parent):
super(PhotoViewer, self).__init__(parent)
self._zoom = 0
self._empty = True
self._scene = QtWidgets.QGraphicsScene(self)
self._photo = QtWidgets.QGraphicsPixmapItem()
self._scene.addItem(self._photo)
self.setScene(self._scene)
self.setTransformationAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
self.setResizeAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(30, 30, 30)))
self.setFrameShape(QtWidgets.QFrame.NoFrame)

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.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
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 toggleDragMode(self):
if self.dragMode() == QtWidgets.QGraphicsView.ScrollHandDrag:
self.setDragMode(QtWidgets.QGraphicsView.NoDrag)
elif not self._photo.pixmap().isNull():
self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)

def mousePressEvent(self, event):
if self._photo.isUnderMouse():
self.photoClicked.emit(self.mapToScene(event.pos()).toPoint())

super(PhotoViewer, self).mousePressEvent(event)


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

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

# Button to change from drag/pan to getting pixel info
self.btnPixInfo = QtWidgets.QToolButton(self)
self.btnPixInfo.setText('Enter pixel info mode')
self.btnPixInfo.clicked.connect(self.pixInfo)
self.editPixInfo = QtWidgets.QLineEdit(self)
self.editPixInfo.setReadOnly(True)
self.viewer.photoClicked.connect(self.photoClicked)

# Arrange layout
VBlayout = QtWidgets.QVBoxLayout(self)
VBlayout.addWidget(self.viewer)
HBlayout = QtWidgets.QHBoxLayout()
HBlayout.setAlignment(QtCore.Qt.AlignLeft)
HBlayout.addWidget(self.btnLoad)
HBlayout.addWidget(self.btnPixInfo)
HBlayout.addWidget(self.editPixInfo)
VBlayout.addLayout(HBlayout)

def loadImage(self):
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;Python Files (*.png)", options=options)

if fileName:
self.viewer.setPhoto(QtGui.QPixmap(fileName))

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

def photoClicked(self, pos):
if self.viewer.dragMode() == QtWidgets.QGraphicsView.NoDrag:
self.editPixInfo.setText('%d, %d' % (pos.x(), pos.y()))


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

最佳答案

您必须使用viewport()的坐标,将其映射到QGraphicsScene中,然后将其映射到QGraphicsPixmapItem中:

rect_scene = self.mapToScene(self.viewport().rect())
rect_item = self._photo.mapFromScene(rect_scene).boundingRect().toRect()
print("Coordinates:\n============")
print("top-left:", rect_item.topLeft())
print("top-right:", rect_item.topRight())
print("bottom-left:", rect_item.bottomLeft())
print("bottom-right:", rect_item.bottomRight())

关于python - 如何在 QGraphicsScene 中找到 QGraphicsPixmapItem 的像素边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59121147/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com