问题
I've made a QGraphicsScene
with a mouseClickEvent
that lets the user create blue squares inside of it. But I want to make the scene grow when an item is placed against its border so that the user never runs out of space on the graphics scene.
What's the best way to make a graphics scene bigger in this case?
回答1:
I suggest doing something like the following:
- Get the bounding rect of all items in the scene using
QGraphicsScene::itemsBoundingRect()
. - Add some padding around that rect to make sure the bounds of the items won't hit the edge of the view. Something like
myRect.adjust(-20, -20, 20, 20)
should be sufficient. - Use
QGraphicsView::fitInView(myRect, Qt::KeepAspectRatio)
to ensure the taken area is within the visible bounds of the view.
That should do it. This code should be called whenever something has changed in the scene. You can use QRectF::intersects() function to find out if the new rect has been placed on the edge of the view.
What's the best way to make a graphics scene bigger in this case?
The GraphicsScene is an infinite coordinate system. Most clients will use itemsBoundingRect()
to get an idea how much space is actually used by items in the scene. If you have cleared the scene, you might want to call QGraphicsScene::setSceneRect(QRectF())
to "make it smaller" again.
Hope that helps.
回答2:
sorry if this is a little bit late(6 years) but I will provide an answer if someone still struggling with this or want another approach.I implement this in mouseReleaseEvent
in the custom class derive from QGraphicsObject
. Note that I initialize the size of my QGraphicsScene
(1000,1000) with the following code.scene->setSceneRect(0,0,1000,1000)
. So here what my code will do. If the Item(the item is draggable) placed against the border, that border will increase. So here is my code:
void MyItem::mouseReleaseEvent(QgraphicsceneMouseEvent* event){
QRectF tempRect = this->scene()->sceneRect();
if(this->scenePos().y() < this->scene()->sceneRect().top()){
tempRect.adjust(0,-200,0,0);
if(this->scenePos().x() < this->scene()->sceneRect().left()){
tempRect.adjust(-200,0,0,0);
}
else if(this->scenePos().x() + 200> this->scene()->sceneRect().right()){
tempRect.adjust(0,0,200,0);
}
}
else if(this->scenePos().y() + 200 > this->scene()->sceneRect().bottom()){
tempRect.adjust(0,0,0,200);
if(this->scenePos().x() < this->scene()->sceneRect().left()){
tempRect.adjust(-200,0,0,0);
}
else if(this->scenePos().x() + 200> this->scene()->sceneRect().right()){
tempRect.adjust(0,0,200,0);
}
}
else if(this->scenePos().x() < this->scene()->sceneRect().left()){
tempRect.adjust(-200,0,0,0);
if(this->scenePos().y() < this->scene()->sceneRect().top()){
tempRect.adjust(0,-200,0,0);
}
else if(this->scenePos().y() + 200 > this->scene()->sceneRect().bottom()){
tempRect.adjust(0,0,0,200);
}
}
else if(this->scenePos().x() + 200> this->scene()->sceneRect().right()){
tempRect.adjust(0,0,200,0);
if(this->scenePos().y() < this->scene()->sceneRect().top()){
tempRect.adjust(0,-200,0,0);
}
else if(this->scenePos().y() + 200 > this->scene()->sceneRect().bottom()){
tempRect.adjust(0,0,0,200);
}
}
this->scene()->setSceneRect(tempRect);
回答3:
I know its late, but for anyone looking for python code here:
class Scene(QtWidgets.QGraphicsScene):
def __init__(self):
super(Scene, self).__init__()
self.setSceneRect(0, 0, 2000, 2000)
self.sceneRect().adjust(-20, -20, 20, 20)
self.old_rect = self.itemsBoundingRect()
def adjust(self):
w = self.sceneRect().width()
h = self.sceneRect().height()
x = self.sceneRect().x()
y = self.sceneRect().y()
adjust_factor = 500
adjust_factor2 = 300
smaller = self.is_smaller()
self.old_rect = self.itemsBoundingRect()
if not self.sceneRect().contains(self.old_rect):
self.setSceneRect(-adjust_factor + x, -adjust_factor + y, adjust_factor + w, adjust_factor + h)
if smaller:
self.setSceneRect(adjust_factor2 + x, adjust_factor2 + y, abs(adjust_factor2 - w), abs(adjust_factor2 - h))
def is_smaller(self):
x = self.old_rect.x()
y = self.old_rect.y()
h = self.old_rect.height()
w = self.old_rect.width()
if ((x <= self.itemsBoundingRect().x()) and (y <= self.itemsBoundingRect().y())
and (h > self.itemsBoundingRect().height()) and (w > self.itemsBoundingRect().width())):
return True
return False
Explanation:
use
self.sceneRect().contains(self.itemBoundingRect)
check whether theitemBoundingRect
is within thesceneRect
, if its not in thesceneRect
then useself.setSceneRect()
to increase thesceneRect
size (Note: make sure you add to the previous sceneRect like shown in the above code).If you also want to decrease the
sceneRect
. Store the olditemBoundingRect
and compare it with the new one, if the newitemSceneRect
Rectangle is smaller then decrease the size by some factor (refer to the above code).
Usage:
you may call the adjust
method from anywhere you like. But Calling the adjust
method from mouseReleaseEvent
worked the best for me.
*If you have any suggestions or query you may comment.
来源:https://stackoverflow.com/questions/4237387/making-qgraphicsscene-bigger-when-a-graphic-item-is-placed-against-its-border