根据任何图像几何形状调整 GraphicView
Adjust GraphicView according to any image geometry
我的 QGraphicsView 应该显示高分辨率的图像。该大小应适合可调整大小的 window。目前,以我想要的方式查看图像,但只能通过为初始视图几何提供一些手动调整的值来查看。这看起来不整洁。我还尝试参考此处发布的解决方案:
我目前的 Window 看起来像这样:
class ImageCheck(Ui_ImageCheck.Ui_MainWindow, QMainWindow):
def __init__(self, parent=None):
super(ImageCheck, self).__init__()
self.setupUi(self)
self.setWindowTitle("Image Analyzer")
self.crop_ratio_w = 1
self.crop_ratio_h = 1
self.path = None
self.scene = QGraphicsScene()
self.scene.clear()
self.image_item = QGraphicsPixmapItem()
# This is the approximate shift in coordinates of my initial view from the window
self.view.setGeometry(self.geometry().x()+ 10, self.geometry().y()+ 39,
self.geometry().width()- 55, self.geometry().height()- 110)
self.view.setAlignment(Qt.AlignCenter)
self.view.setFrameShape(QFrame.NoFrame)
def setImage(self, path):
self.path = path
self.crop_ratio_w = self.pixmap.width() / self.view.width()
self.crop_ratio_h = self.pixmap.height() / self.view.height()
pixmap = QPixmap(path)
smaller_pixmap = pixmap.scaled(self.view.width(), self.view.height(),
Qt.IgnoreAspectRatio, t.FastTransformation)
self.image_item.setPixmap(smaller_pixmap)
self.scene.addItem(self.image_item)
self.scene.setSceneRect(0, 0, self.view.width(), self.view.height())
self.view.setGeometry(0, 0, self.view.width(), self.view.height())
self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.view.setScene(self.scene)
self.view.setSceneSize()
def resizeEvent(self, event):
self.view.setGeometry(self.geometry().x()+ 10, self.geometry().y()+ 39,
self.geometry().width()- 55, self.geometry().height()- 110)
self.setImage(self.path)
当我试图确定两点之间的距离时,我的手动覆盖可能不是一个好主意。即使是缩放距离也给我一个稍微错误的值。
我不能使用你的代码,因为有很多隐藏的东西所以我会提出下一个解决方案,即每次 window 改变它的大小时,根据场景重新缩放视图。我还实现了一个信号,根据图像的坐标传输图像中的点击信息。
from PyQt5 import QtCore, QtGui, QtWidgets
class ClickableGraphicsView(QtWidgets.QGraphicsView):
clicked = QtCore.pyqtSignal(QtCore.QPoint)
def __init__(self, parent=None):
super(ClickableGraphicsView, self).__init__(parent)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
self.pixmap_item = None
def setImage(self, path):
pixmap = QtGui.QPixmap(path)
self.pixmap_item = self.scene().addPixmap(pixmap)
self.pixmap_item.setShapeMode(
QtWidgets.QGraphicsPixmapItem.BoundingRectShape
)
def mousePressEvent(self, event):
if self.pixmap_item is not None:
if self.pixmap_item == self.itemAt(event.pos()):
sp = self.mapToScene(event.pos())
lp = self.pixmap_item.mapToItem(self.pixmap_item, sp)
p = lp.toPoint()
if self.pixmap_item.pixmap().rect().contains(p):
self.clicked.emit(p)
super(ClickableGraphicsView, self).mousePressEvent(event)
def resizeEvent(self, event):
self.fitInView(self.sceneRect(), QtCore.Qt.IgnoreAspectRatio)
super(ClickableGraphicsView, self).resizeEvent(event)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setWindowTitle("Image Analyzer")
view = ClickableGraphicsView()
view.clicked.connect(print)
view.setImage("image.jpg")
label = QtWidgets.QLabel("Distance")
display = QtWidgets.QLCDNumber()
buttonbox = QtWidgets.QDialogButtonBox(
QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel
)
widget = QtWidgets.QWidget()
self.setCentralWidget(widget)
lay = QtWidgets.QGridLayout(widget)
lay.addWidget(view, 0, 0, 1, 2)
hlay = QtWidgets.QHBoxLayout()
hlay.addWidget(label)
hlay.addWidget(display)
hlay.addStretch()
lay.addLayout(hlay, 1, 0)
lay.addWidget(buttonbox, 1, 1)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
我的 QGraphicsView 应该显示高分辨率的图像。该大小应适合可调整大小的 window。目前,以我想要的方式查看图像,但只能通过为初始视图几何提供一些手动调整的值来查看。这看起来不整洁。我还尝试参考此处发布的解决方案:
我目前的 Window 看起来像这样:
class ImageCheck(Ui_ImageCheck.Ui_MainWindow, QMainWindow):
def __init__(self, parent=None):
super(ImageCheck, self).__init__()
self.setupUi(self)
self.setWindowTitle("Image Analyzer")
self.crop_ratio_w = 1
self.crop_ratio_h = 1
self.path = None
self.scene = QGraphicsScene()
self.scene.clear()
self.image_item = QGraphicsPixmapItem()
# This is the approximate shift in coordinates of my initial view from the window
self.view.setGeometry(self.geometry().x()+ 10, self.geometry().y()+ 39,
self.geometry().width()- 55, self.geometry().height()- 110)
self.view.setAlignment(Qt.AlignCenter)
self.view.setFrameShape(QFrame.NoFrame)
def setImage(self, path):
self.path = path
self.crop_ratio_w = self.pixmap.width() / self.view.width()
self.crop_ratio_h = self.pixmap.height() / self.view.height()
pixmap = QPixmap(path)
smaller_pixmap = pixmap.scaled(self.view.width(), self.view.height(),
Qt.IgnoreAspectRatio, t.FastTransformation)
self.image_item.setPixmap(smaller_pixmap)
self.scene.addItem(self.image_item)
self.scene.setSceneRect(0, 0, self.view.width(), self.view.height())
self.view.setGeometry(0, 0, self.view.width(), self.view.height())
self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.view.setScene(self.scene)
self.view.setSceneSize()
def resizeEvent(self, event):
self.view.setGeometry(self.geometry().x()+ 10, self.geometry().y()+ 39,
self.geometry().width()- 55, self.geometry().height()- 110)
self.setImage(self.path)
当我试图确定两点之间的距离时,我的手动覆盖可能不是一个好主意。即使是缩放距离也给我一个稍微错误的值。
我不能使用你的代码,因为有很多隐藏的东西所以我会提出下一个解决方案,即每次 window 改变它的大小时,根据场景重新缩放视图。我还实现了一个信号,根据图像的坐标传输图像中的点击信息。
from PyQt5 import QtCore, QtGui, QtWidgets
class ClickableGraphicsView(QtWidgets.QGraphicsView):
clicked = QtCore.pyqtSignal(QtCore.QPoint)
def __init__(self, parent=None):
super(ClickableGraphicsView, self).__init__(parent)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
self.pixmap_item = None
def setImage(self, path):
pixmap = QtGui.QPixmap(path)
self.pixmap_item = self.scene().addPixmap(pixmap)
self.pixmap_item.setShapeMode(
QtWidgets.QGraphicsPixmapItem.BoundingRectShape
)
def mousePressEvent(self, event):
if self.pixmap_item is not None:
if self.pixmap_item == self.itemAt(event.pos()):
sp = self.mapToScene(event.pos())
lp = self.pixmap_item.mapToItem(self.pixmap_item, sp)
p = lp.toPoint()
if self.pixmap_item.pixmap().rect().contains(p):
self.clicked.emit(p)
super(ClickableGraphicsView, self).mousePressEvent(event)
def resizeEvent(self, event):
self.fitInView(self.sceneRect(), QtCore.Qt.IgnoreAspectRatio)
super(ClickableGraphicsView, self).resizeEvent(event)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setWindowTitle("Image Analyzer")
view = ClickableGraphicsView()
view.clicked.connect(print)
view.setImage("image.jpg")
label = QtWidgets.QLabel("Distance")
display = QtWidgets.QLCDNumber()
buttonbox = QtWidgets.QDialogButtonBox(
QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel
)
widget = QtWidgets.QWidget()
self.setCentralWidget(widget)
lay = QtWidgets.QGridLayout(widget)
lay.addWidget(view, 0, 0, 1, 2)
hlay = QtWidgets.QHBoxLayout()
hlay.addWidget(label)
hlay.addWidget(display)
hlay.addStretch()
lay.addLayout(hlay, 1, 0)
lay.addWidget(buttonbox, 1, 1)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())