As the docs point out:
alignment : Qt::Alignment
This property holds the alignment of the
scene in the view when the whole scene is visible.
If the whole scene is visible in the view, (i.e., there are no visible
scroll bars,) the view's alignment will decide where the scene will be
rendered in the view. For example, if the alignment is
Qt::AlignCenter, which is default, the scene will be centered in the
view, and if the alignment is (Qt::AlignLeft | Qt::AlignTop), the
scene will be rendered in the top-left corner of the view.
So, by default, the scenerect is centered with the viewport of the QGraphicsView, and in the case of having the same size, the behavior you point out is observed, but in the second case the property of the centering is highlighted.
So the solution is to establish the alignment to:
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_())
Explanation:
To understand what the scenerect is first, it must be understood that it is the QGraphicsView and the QGraphicsScene, these concepts are explained with an analogy to the recording of a movie, the QGraphicsView would be the camera, the QGraphicsScene represents what is recorded, ie the scene. The scene is delimited by the sceneRect, if the camera is very close to the scene, its limits will not be observed, but if the camera is far away, the scenerect projection in the camera will not occupy the whole screen, so it will have to be aligned in some position, in the case of QGraphicsView the alignment property is used.
why the scene is no longer centered in the view if I use setSceneRect(50, 50, 150, 150)?
To answer I use the following example where to make the scenerect visible I use a 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_())
As you can see the alignment is not about QRectF(0, 0, w, h) but the center of QRectF(x, y, w, h) which in this case is (100,100). So keep centered on sceneRect in the QGraphicsView.