放大QGraphicsItem以适应QGraphicsView

问题描述 投票:2回答:1

我正在尝试创建一个QGraphicsView,允许有人缩放当前的QGraphicsItem以适应QGraphicsView窗口的大小。

我已经覆盖了QGraphicsItem来创建一个自定义版本,并且我实现了一些方法,因此它知道它被缩放了多少(它总是与原始的成比例,因此只有一个比例因子 - 宽度和高度相同)。

所以在scaleFactor setter我有以下内容:

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之一。

这在第一次时效果很好 - 我的图像比视口大,并且它很好地缩小以适合窗口(至少宽度方向)。但是,如果我再次按下按钮,scaleFactorXitem宽度和高度的相同值将返回。

你能改变一个图像的boundingRect吗?如果没有,我该怎么办?

c++ qt qt4 qgraphicsview qgraphicsitem
1个回答
3
投票

首先,QGraphicsItem::boundingRect()返回rect的副本。更改它对实际项目没有影响。要更改项目的几何图形,您需要覆盖该函数并返回不同的矩形。当你真正改变它时,请调用prepareGeometryChange()

现在,如果你想要的是在QGraphicsView的视口中拟合项目,请使用QGraphicsView::fitInView()

更改项目的转换与更改从场景到视图的转换非常不同。前者更改项目相对于其他项目在场景中的放置方式。后者保持关系,仅影响场景“反射”到视图上的方式。

如果场景中只有一个项目,则没有多大区别。请记住,当您处理更复杂的场景时,项目转换会处理您的世界的数学模型,而不是如何查看它。

编辑:

我只是重读你的代码。事实证明你正在计算错误的比例因子。这是一个基本的,未经测试的代码:

QRect itemSize = graphicsView->mapFromScene(item->sceneBoundingRect()).boundingRect().size();
QRect scaledSize =itemSize.scale(graphicsView->viewport().size(), Qt::KeepAspectRatio);
double ratio = qMin((double)scaledSize.width()/itemSize().width(), (double)scaledSize.height()/itemSize().height());
item->setTransform(QTransform::fromScale(ratio,ratio), true);

关键是使用sceneBoundingRect而不是boundingRect,因为boundingRect是项本地边界,无论项目变换如何都始终相同。并且在应用所有transformations之后,sceneBoundingRect是边界。

© www.soinside.com 2019 - 2024. All rights reserved.