缩放 QGraphicsItem 以适合 QGraphicsView
我正在尝试创建一个QGraphicsView
,它允许某人缩放当前QGraphicsItem
以适应QGraphicsView
窗口的大小。
我已经重写了 QGraphicsItem 来创建自定义版本,并且我实现了一些方法,以便它知道它已缩放了多少(始终与原始版本成正比,因此只有一个缩放因子 - 相同)对于宽度和高度)。
因此,在 scaleFactor
设置器中,我有以下内容:
void ImagePixmapItem::setScaleFactor(float sf){
scaleFactor = sf;
this->boundingRect().setWidth(this->boundingRect().width()*scaleFactor);
this->boundingRect().setHeight(this->boundingRect().height()*scaleFactor);
}
在我的主窗体中,我在按钮中具有以下内容:
QRect portRect = ui->graphicsView->viewport()->rect();
double scaleFactorX;
if(portRect.width() <= (item->boundingRect().size().width()))
scaleFactorX =portRect.width() /(item->boundingRect().size().width());
else
scaleFactorX = (item->boundingRect().size().width())/portRect.width();
qDebug("Scalefactor: %4.3f \n", scaleFactorX);
qDebug("item width: %4.3f \n", item->boundingRect().size().width());
qDebug("item height: %4.3f \n", item->boundingRect().size().height());
item->setScaleFactor(scaleFactorX);
item->scale(scaleFactorX,scaleFactorX);
其中 item
是其中之一 ImagePixmapItems.
第一次效果很好 - 我的图像比视口大,并且它可以很好地缩小以适应窗口(至少在宽度方面)。但是,如果我再次点击按钮,则 scaleFactorX
和 item
宽度和高度会返回相同的值。
变换后的图像可以更改其 boundingRect
吗?如果没有,我该怎么办?
I am trying to create a QGraphicsView
that will allow someone to scale the current QGraphicsItem
to fit the size of the QGraphicsView
window.
I have overridden QGraphicsItem
to create a custom version, and I implemented some methods so it knows how much it has been scaled (which is always proportional to the original, so there is only one scale factor - the same for width and height).
So in the scaleFactor
setter I have the following:
void ImagePixmapItem::setScaleFactor(float sf){
scaleFactor = sf;
this->boundingRect().setWidth(this->boundingRect().width()*scaleFactor);
this->boundingRect().setHeight(this->boundingRect().height()*scaleFactor);
}
And in my main form, I have the following in a button:
QRect portRect = ui->graphicsView->viewport()->rect();
double scaleFactorX;
if(portRect.width() <= (item->boundingRect().size().width()))
scaleFactorX =portRect.width() /(item->boundingRect().size().width());
else
scaleFactorX = (item->boundingRect().size().width())/portRect.width();
qDebug("Scalefactor: %4.3f \n", scaleFactorX);
qDebug("item width: %4.3f \n", item->boundingRect().size().width());
qDebug("item height: %4.3f \n", item->boundingRect().size().height());
item->setScaleFactor(scaleFactorX);
item->scale(scaleFactorX,scaleFactorX);
Where item
is one of those ImagePixmapItem
s.
This works good the first time time - my image is larger than the viewport, and it scales down nicely to fit the window (at least width wise). However, if I hit the button again, the same value for scaleFactorX
and item
width and height come back.
Can you change the boundingRect
of an image after it has been transformed? If not, what should I do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,
QGraphicsItem::boundingRect()
返回矩形的副本。更改它对实际项目没有影响。要更改项目的几何形状,您需要覆盖该函数并返回不同的矩形。并在实际更改时调用prepareGeometryChange()
它。现在,如果您想要的只是使项目适合 QGraphicsView 的视口,请使用
QGraphicsView::fitInView()
。更改项目的变换与更改从场景到视图的变换有很大不同。前者改变了项目在场景中相对于其他项目的放置方式。后者保持关系并且仅影响场景如何“反射”到视图上。
如果场景中只有一个项目,那并没有多大区别。请记住,当您处理更复杂的场景时,项目转换涉及您的世界的数学模型,而不是如何查看它。
编辑:
我刚刚重读了您的代码。事实证明你计算的比例因子是错误的。这是一个基本的、未经测试的代码:
重点是使用
sceneBoundingRect
而不是boundingRect
因为boundingRect
是项目本地边界,它始终是无论项目变换如何,都相同。 sceneBoundingRect 是应用所有变换
后的边界。First of all,
QGraphicsItem::boundingRect()
returns a copy of the rect. Changing it has no effect on the actual item. To change an item's geometry, you need to override that function and return a different rect. And callprepareGeometryChange()
when you actually change it.Now, if all you want is to fit the item in QGraphicsView's viewport, use
QGraphicsView::fitInView()
.Changing the transformation of an item is very different from changing the transformation from the scene to the view. The former changes how the item is placed in the scene in relation to other items. The later keeps the relation and only affect how the scene is "reflected" onto the view.
It doesn't make much difference if you have a single item in the scene. Just keep in mind when you are dealing more complex scene that item transformation deals with the mathematical model of your world, not how to view it.
Edit:
I just reread your code. It turns out you are calculating the scale factor wrong. Here's a basic, non-tested code:
The point is to use
sceneBoundingRect
instead ofboundingRect
sinceboundingRect
is the item local bounds which is always the same regardless of item transform. And sceneBoundingRect is the bounds after alltransformations
are applied.