Issue
I am writing a visualizer of a tree like structure (imagine mindmapping although it's nothing like that) and want to be able to move view to newly unfolded objects immediately after they are painted to the canvas.
I made this example of my problem:
import sys
from PyQt6.QtWidgets import QGraphicsScene, QGraphicsView, QApplication, QGraphicsRectItem
class MyRect(QGraphicsRectItem):
def __init__(self,x, y, width, height):
super().__init__(x, y, width, height)
self.pressed = False
def mousePressEvent(self, event):
self.pressed = True
def mouseReleaseEvent(self, event):
if self.pressed:
self.pressed = False
x = self.boundingRect().toRect().x()
self.scene().addItem(MyRect(x + 1000, 100, 100, 100))
self.ensureVisible(1100, 100, 100, 100)
app = QApplication(sys.argv)
scene = QGraphicsScene()
scene.addItem(MyRect(100,100,100,100))
view = QGraphicsView(scene)
view.setGeometry(0,0, 800, 500)
view.show()
app.exec()
It adds a rectangle. Upon clicking on it it adds another one, which is not seeen because it's out of current viewport. Calling ensureVisible on it's coordinates doesn't work. My guess is that I call ensureVisible method "too soon" before some behind the curtain paint method happens. What is the proper way or proper place to call it so the newly added rectangle gets shown (by moving the viewport)? I tried many variations of ensure visible on coordinates, item, viewport, nothing seems to work
Solution
Found a solution, or a walkaround. EnsureVisible(..) apparently doesn't work, since the geometry of the viewport is not up to date. What "fixed" the problem is calling sceneRect() on the scene (which should be only informative in this case according to documentation - or how I understand it).
So working example is:
import sys
from PyQt6.QtWidgets import QGraphicsScene, QGraphicsView, QApplication, QGraphicsRectItem
class MyRect(QGraphicsRectItem):
def __init__(self,x, y, width, height):
super().__init__(x, y, width, height)
self.pressed = False
def mousePressEvent(self, event):
self.pressed = True
def mouseReleaseEvent(self, event):
if self.pressed:
self.pressed = False
x = self.boundingRect().toRect().x()
self.scene().addItem(MyRect(x + 1000, 100, 100, 100))
self.scene().sceneRect() #does magic to update view's capability to scroll
self.ensureVisible(1100, 100, 100, 100)
app = QApplication(sys.argv)
scene = QGraphicsScene()
scene.addItem(MyRect(100,100,100,100))
view = QGraphicsView(scene)
view.setGeometry(0,0, 800, 500)
view.show()
app.exec()
Answered By - Michal Pravda
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.