PyQt5:我无法理解 QGraphicsScene 的 setSceneRect(x, y, w, h)

2024-04-24

我看到有人说如果你想把QGraphicsScene的坐标原点放在QGraphicsView的原点,即左上角。您需要让它们具有相同的大小。

所以这就是我所做的:

import sys
from PyQt5.QtWidgets import QApplication, QGraphicsLineItem, 
QGraphicsScene, QGraphicsView


class Demo(QGraphicsView):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(300, 300)

        self.line = QGraphicsLineItem()
        self.line.setLine(0, 0, 100, 100)

        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 300, 300)
        self.scene.addItem(self.line)

        self.setScene(self.scene)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

视图的大小是 300x300,我使用setSceneRect()确保场景的大小为 300x300。

In this case, the Scene's origin is at top-left corner. enter image description here

However, when I use setSceneRect(0, 0, 150, 150), the origin is not there, but at (75, 75)! enter image description here

为什么?我认为前两个参数setSceneRect(x, y, w, h)设置坐标原点所在的位置。当Scene小于View时,如何确保Scene的原点在左上角?

任何帮助,将不胜感激!


As the docs https://doc.qt.io/qt-5/qgraphicsview.html#alignment-prop指出:

对齐:Qt::对齐

该属性保存了对齐方式 当整个场景可见时视图中的场景。

如果整个场景在视图中可见(即,没有可见的 滚动条)视图的对齐方式将决定场景的位置 呈现在视图中。例如,如果对齐方式是 Qt::AlignCenter,默认情况下,场景将居中 视图,如果对齐方式是 (Qt::AlignLeft | Qt::AlignTop),则 场景将渲染在视图的左上角。

因此,默认情况下,场景矩形与 QGraphicsView 的视口居中,并且在具有相同大小的情况下,会观察到您指出的行为,但在第二种情况下,居中的属性会突出显示。

因此,解决方案是建立以下一致性:

import sys
from PyQt5.QtWidgets import QApplication, QGraphicsLineItem, QGraphicsScene, QGraphicsView
from PyQt5.QtCore import Qt

class Demo(QGraphicsView):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(300, 300)

        self.line = QGraphicsLineItem()
        self.line.setLine(0, 0, 100, 100)

        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 150, 150)
        self.scene.addItem(self.line)

        self.setScene(self.scene)
        self.setAlignment(Qt.AlignTop | Qt.AlignLeft)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

解释:

要理解sceneect是什么,首先必须明白它是QGraphicsView和QGraphicsScene,这些概念用电影录制的类比来解释,QGraphicsView就是相机,QGraphicsScene代表录制的内容,即现场。场景由 sceneRect 界定,如果相机距离场景很近,则不会遵守其限制,但如果相机较远,则相机中的 scenerect 投影不会占据整个屏幕,因此会有要在某个位置对齐,在 QGraphicsView 的情况下,使用对齐属性。


如果我使用 setSceneRect(50, 50, 150, 150),为什么场景不再在视图中居中?

为了回答我使用以下示例,在其中使 sceneect 可见,我使用 QGraphicsRectItem:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class Demo(QtWidgets.QGraphicsView):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(300, 300)

        self.line = QtWidgets.QGraphicsLineItem()
        self.line.setLine(0, 0, 100, 100)

        self.scene = QtWidgets.QGraphicsScene()
        self.scene.setSceneRect(50, 50, 150, 150)
        self.scene.addItem(self.line)
        rect_item = self.scene.addRect(QtCore.QRectF(50, 50, 150, 150))
        rect_item.setPen(QtGui.QPen(QtGui.QColor("green")))

        self.setScene(self.scene)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

正如您所看到的,对齐不是关于 QRectF(0, 0, w, h) 而是 QRectF(x, y, w, h) 的中心,在本例中是 (100,100)。因此,请保持以 QGraphicsView 中的 sceneRect 为中心。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PyQt5:我无法理解 QGraphicsScene 的 setSceneRect(x, y, w, h) 的相关文章

随机推荐