将Zoom QGraphicsItem调整适应QGraphicsView

3
我正在尝试创建一个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是那些ImagePixmapItem之一。

第一次使用时效果很好 - 我的图像比视口大,它可以很好地缩小以适应窗口(至少在宽度方面)。但是,如果我再次点击按钮,则会返回相同的scaleFactorXitem宽度和高度的值。

您能否在转换后更改图像的boundingRect?如果不能,我该怎么办?

1个回答

3
首先,QGraphicsItem::boundingRect() 返回矩形的一个副本。更改它不会对实际项产生影响。要更改项的几何形状,您需要重写该函数并返回不同的矩形。在实际更改时调用 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是物品的本地边界,无论物品变换如何,它始终相同。而sceneBoundingRect是在应用所有transformations后的边界。

如果我使用fitInView,它是否会实际缩放ITEM本身?请记住,如果场景中有多个项,我实际上想要操作具有焦点的单个项以适应视图,而不仅仅是缩放视图本身以适应视图中的项。 - Derek
我没有意识到你想要操纵单个项目的大小。那么 fitToView 不是答案。抱歉。然而,你的 setScaleFactor() 没有任何效果,因为它只是设置了一个临时值。请看我的编辑以缩放单个项目。 - Stephen Chu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接