Issue
I am trying to understand the behaviour of QGraphicsView.fitInView
, but it just seems bizarre to me. I have the following minimal example code
import sys
from PyQt5.QtGui import QPen
from PyQt5.QtCore import Qt, QLineF
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QWidget, QApplication
class MyGraphicsScene(QGraphicsScene):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setSceneRect(0, 0, 250, 500)
pen = QPen(Qt.black, 1, Qt.DashLine)
pen.setCosmetic(True)
self.addLine(QLineF(self.sceneRect().topLeft(), self.sceneRect().topRight()), pen)
self.addLine(QLineF(self.sceneRect().bottomLeft(), self.sceneRect().bottomRight()), pen)
self.addLine(QLineF(self.sceneRect().topLeft(), self.sceneRect().bottomLeft()), pen)
self.addLine(QLineF(self.sceneRect().topRight(), self.sceneRect().bottomRight()), pen)
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.view = QGraphicsView(self)
self.view.setGeometry(0, 0, 300, 300)
self.scene = MyGraphicsScene()
self.view.setScene(self.scene)
self.view.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
app = QApplication(sys.argv)
window = MyWidget()
window.show()
sys.exit(app.exec_())
Now, what I want to achieve is that I can set the scene rect to be whatever I want, and then call QGraphicsView.fitInView
to appropriately zoom in or scale the scene so it that it covers the entire graphics view. In this simple example, I would expect the code to zoom into the rectangle I've drawn (which is just the scene bounding box) across the entire graphics view. So the top and bottom edge should be touching the borders of the graphics view. However, this is what I get instead
What is especially bizarre is that if I don't call fitInView
, then the box I draw will be larger than the graphics view and will force a vertical scrollbar.
My questions are two-fold:
- Why is this happening? Clearly, I'm not understanding the behaviour of
fitInView
, and - How can I achieve my desired behaviour, i.e. scale the graphics scene/view properly so the rectangle will reach the edges of the graphics view?
Solution
The problem is caused because the QGraphicsView has not been rendered, therefore this method fails. A workaround is to execute it a moment after it is shown:
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.view = QGraphicsView(self)
self.view.setGeometry(0, 0, 300, 300)
self.scene = MyGraphicsScene()
self.view.setScene(self.scene)
QTimer.singleShot(0, self.handle_timeout)
def handle_timeout(self):
self.view.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
Answered By - eyllanesc
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.