【问题标题】:Moving a QPixmap to the corner of a QGraphicsScene将 QPixmap 移动到 QGraphicsScene 的角落
【发布时间】:2011-11-06 02:07:26
【问题描述】:

我有一个 QGraphicsView 和一个 QGraphicsScene 像这样连接:

graphicsScene->setSceneRect(this->graphicsView->rect());
graphicsView->setScene(this->Scene);

然后我加载图像并将其添加到场景中:

  QPixmap pixmap;
  pixmap.load(fileName);

  pixmap = pixmap.scaled(this->graphicsView->size());
  QGraphicsPixmapItem* item = this->Scene->addPixmap(pixmap);

现在,如文档中所述,图像角位于 (0,0),这不是 graphicsScene 的角。我知道我可以通过以下方式定位生成的像素图:

item->setPos(this->Scene->sceneRect().x(), this->Scene->sceneRect().y());

但是,我似乎无法理解场景或视图的矩形坐标。谁能解释我如何将像素图移动到场景/视图的角落?

谢谢,

大卫

编辑:这是完整的表单构造函数。 QGraphicsView 是在 Qt Designer 中创建的,位于 GridLayout 内部:

Form::Form(QWidget *parent)
    : QWidget(parent)
{
  setupUi(this);

  QGraphicsScene* scene = new QGraphicsScene;
  scene->setSceneRect(this->graphicsView->rect());
  this->graphicsView->setScene(scene);

  QPixmap pixmap;
  pixmap.load("image.png");
  pixmap = pixmap.scaled(this->graphicsView->size());

  scene->addPixmap(pixmap);

}

我也试过这个:

  QGraphicsScene* scene = new QGraphicsScene;
  this->graphicsView->setScene(scene);

  QPixmap pixmap;
  pixmap.load("/home/doriad/glasses.jpg");

  QGraphicsPixmapItem * item = scene->addPixmap(pixmap);
  this->graphicsView->fitInView (item);

但图像看起来很小,而不是像我期望的那样填满视图。谁能解释一下?

完整的项目和图片可在此处获得:daviddoria.com/Uploads/qt/QPixmapPosition

【问题讨论】:

  • 您是对场景的角落感兴趣,还是对视图的角落感兴趣,不管它可能位于何处?
  • 我只想要视图中的一个场景,所以理想情况下我希望场景的角落与视图的角落对齐 - 然后像素图的角落可以对齐它会是一样的。

标签: qt qt4


【解决方案1】:

不用担心自己缩放像素图甚至翻译它,让视图为您完成。

使用graphicsView->fitInView(pixmap);,但您应该阅读以下文档:

Qt 的Graphics View Framework

void QGraphicsView::setSceneRect (QRectF )

void QGraphicsView::translate ( qreal dx, qreal dy )

void QGraphicsView::fitInView ( const QGraphicsItem * item, ... )

QGraphicsScene 和 QGraphicsView 交互的方式是,您可以拥有一个具有至少一个或多个视图的单一场景。

我喜欢想到的一个很好的例子是放大地图的一部分,并在角落里看到整个地图的迷你视图。有两个视图,一个是部分地图,一个是整个地图,一个场景是地图本身。

因此,您将项目放入场景中,并且场景中的所有项目都在大小上相互绘制。默认情况下,视图的“场景矩形”会缩放以适应视图中的项目,直到场景中的一个单位是视图中的一个像素,或者直到它需要缩小以适应场景中的所有项目。

如果您调用 fitInView(someItem) 它应该缩放您的场景视图,以便指定的项目填充它并转换视图使其居中。如果您需要更多地转换或缩放它,请使用 QGraphicsView 中的translatescale 函数。

当您在场景的坐标系和使用 QRect 或 QPoint 的视图之间跳转时,请使用辅助函数:QGraphicsView 中的mapToScenemapFromScene

【讨论】:

  • 感谢您的精彩解释。但是,我以为我按照您所说的进行了操作,但是后来我尝试了这个: Form::Form(QWidget parent) : QWidget(parent) { setupUi(this); QGraphicsScene 场景 = 新 QGraphicsScene; this->graphicsView->setScene(场景); QPixmap 像素图; pixmap.load("/home/doriad/glasses.jpg"); QGraphicsPixmapItem * item = scene->addPixmap(pixmap); this->graphicsView->fitInView (item);但图像看起来很小并且位于视图的中心。你能解释一下这种行为吗?
  • @DavidDoria 看看我在下面添加到您的答案中的评论。我很高兴我的回答在某种程度上有所帮助。
【解决方案2】:

试试这个:

QGraphicsScene* scene = new QGraphicsScene;
scene->setSceneRect(graphicsView->sceneRect());
QPixmap pixmap;
pixmap.load("/home/doriad/glasses.jpg");
pixmap=pixmap.scaledToWidth(this->graphicsView->width());
QGraphicsPixmapItem * item = scene->addPixmap(pixmap);
graphicsView->setScene(scene);

默认情况下,像素图在场景中的 (0,0) 处,场景在视图中的 (0,0) 处。 QWidgets 的大小是像素。如果您有一个屏幕大小的 QGraphicsView 并且分辨率为 1440 x 900,您可以在该视图中将对象从 (0,0) 或屏幕左上角定位到 (1440,900) 右下角的屏幕。大多数 QGraphicsItems 是参考它们的左上角放置的。因此,将像素图放置在 (0,0) 处会将像素图的左上角与其所在场景的左上角对齐。如果您的像素图“悬在视图的底部”,请尝试使用:

pixmap=pixmap.scaledToHeight(this->graphicsView->height());

如果你使用函数:

this->graphicsView->fitInView (item);

graphicsView 只会滚动到您的项目适合视图的位置。

【讨论】:

【解决方案3】:

我下载了 David 的代码并以两种方式运行它。点击链接查看结果。

1) 与pixmap=pixmap.scaledToHeight(this->graphicsView->height());

2) 与pixmap=pixmap.scaledToHeight(200);

我无法解释为什么会发生这种情况,但我认为这将是一个有用的数据点。

【讨论】:

  • 这两种方式中的任何一种都有效吗?还是您看到了我描述的相同行为?
  • 点击链接。我用这两种方法截取了行为的屏幕截图。
【解决方案4】:

原来问题在于 GraphicsView 在布局中。在我的示例中,图像的大小调整是在 Form 构造函数中完成的。显然这是在布局形成之前?我将代码移到了一个按钮上,当我单击它时,图像的大小与我期望的一样。

通过继承 QGraphicsView 并重新实现,我让图像保持在布局中的 GraphicsView 大小:

class CustomGraphicsView: public QGraphicsView
{
  Q_OBJECT
    {
          void resizeEvent ( QResizeEvent * event )
          {
            emit resized();
          }

        signals:
          void resized();
    }

然后我将这个 resized() 信号连接到一个简单地调用this->View->fitInView (this->ImageToTraceItem);的槽

大卫

【讨论】:

  • 另一种无需按钮即可实现此目的的方法是让它发生在表单的显示事件上。 #include <QShowEvent> 并重新实现 void showEvent(QShowEvent*){ this->View->fitInView(this->ImageToTraceItem);}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-25
  • 2023-04-10
相关资源
最近更新 更多