【问题标题】:Can't zoom in after implementing fitInView() in Qt在 Qt 中实现 fitInView() 后无法放大
【发布时间】:2022-07-21 16:39:58
【问题描述】:

我正在使用 Qt 进行一个项目,我要做的就是在背景中添加一张图片(可以是 png 或 jpg)。

我用 QGraphicsView 和 QGraphicsScene 创建了一个带有场景的视图。

QGraphicsPixmapItem * image = new QGraphicsPixmapItem(QPixmap("...../world_map.png"));
int imageWidth = image->pixmap().width();
int imageHeight = image->pixmap().height();
image->setOffset(- imageWidth / 2, -imageHeight / 2);
image->setPos(0, 0);

QGraphicsScene *scene = new QGraphicsScene();
scene->setSceneRect(-imageWidth / 2, -imageHeight / 2, imageWidth, imageHeight);
QGraphicsView * gv = new QGraphicsView();
gv->setScene(scene);
gv->scene()->addItem(image);

我得到以下输出:

但我希望整个图像适合视图,同时保持纵横比。因此,我创建了一个继承自 QGraphicsView 的自定义类,并编写了以下内容:

void MyView::resizeEvent(QResizeEvent *event)
{
    QGraphicsView::resizeEvent(event);
    fitInView(sceneRect(), Qt::KeepAspectRatio);
}

现在,我得到以下输出:

这是可取的,但我现在无法放大视图。我只能缩小。 附言- 我写了一个mouseWheelEvent函数来放大和缩小。

可以做些什么来实现设施的放大?

编辑:这是我实现放大/缩小的方式:

void MyView::wheelEvent(QWheelEvent *e)
{
    static const double factor = 1.1;
    static double currentScale = 1.0;
    static const double scaleMin = 1.0;
    ViewportAnchor oldAnchor = transformationAnchor();

    setTransformationAnchor(QGraphicsView::AnchorUnderMouse); // set focus to mouse coords

    //if (e->delta() > 0)
    if (e->angleDelta().y() > 0){
        scale(factor, factor);
        currentScale *= factor;
    }
    else if (currentScale > scaleMin){
        scale(1 / factor, 1 / factor);
        currentScale /= factor;
    }
    setTransformationAnchor(oldAnchor); // reset anchor
}

【问题讨论】:

  • 你应该展示mouseWheelEvent是如何实现的。要进行 zoomIn/zoomOut,只需获取视图的当前 scaleX/Y 值并将其乘以适当的因子即可。
  • @rafix07 我已经编辑了我的问题并添加了wheelEvent
  • @rafix07 QGraphicsView::scale(qreal sx, qreal sy) 将当前视图转换缩放(sx, sy)。因此,每次调用 scale 时都会缩放当前视图转换。此外,当我删除 fitInView 时,缩放效果很好。
  • fitInView 有一些东西阻止了放大(即增加当前视图转换的比例)。缩小在两种情况下都可以正常工作(即有或没有fitInView
  • 对不起我之前的评论,我的错。我错了。

标签: c++ qt qt-creator qgraphicsview qgraphicsscene


【解决方案1】:

我遇到了同样的问题。 fitInView 中的某些东西使得 transform 的缩放上限为 1。如果在缩放时打印 QGraphicsView::transform(),会发现 m11 和 m22 的值不能大于 1(调用 fitInView 后)。

解决方案 1:在 fitInView 之后调用 resetTransfrom()。不推荐,因为它会重置调用。

解决方案 2:不要使用 fitInView,我会编写自己的 fitInView 版本。

注意,在我的实现中,我知道场景中只有一个项目。我还更改了场景矩形大小,其他人可能不需要。 ImageViwer 是 qgraphicsview 的子类。

void ImageViewer::resizeEvent(QResizeEvent *) {
  QList<QGraphicsItem *> i = items();
  int window_w = width();
  if (window_w == 0 || i.size() != 1) return;

  auto *item = qgraphicsitem_cast<QGraphicsPixmapItem *>(i[0]);
  qreal img_w = static_cast<double>(item->pixmap().width());
  qreal factor = window_w / img_w;
  item->setScale(factor);

  QRectF rect = item->boundingRect();
  rect.setHeight(height());
  rect.setWidth(width());
  rect.moveCenter(item->boundingRect().center());

  QGraphicsScene *s = scene();
  s->setSceneRect(rect);

  item->setTransformOriginPoint(item->boundingRect().center());
  centerOn(item);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 2012-12-31
    相关资源
    最近更新 更多