在 QGraphicsScene 中缩放和旋转的 QGraphicsPixmapItem 的奇怪绘图行为

Posted

技术标签:

【中文标题】在 QGraphicsScene 中缩放和旋转的 QGraphicsPixmapItem 的奇怪绘图行为【英文标题】:Strange drawing behavior for QGraphicsPixmapItem in a zoomed and rotated in QGraphicsScene 【发布时间】:2016-10-18 14:00:10 【问题描述】:

我在 QGraphicsScene 中有一个 QGraphicsPixmapItem,然后我在 QGraphicsView 中放大并旋转它。如果没有旋转或者我没有放大太远,一切都很好,但是当我放大(像素非常明显)并围绕奇怪的事情发生旋转时。有时图像看起来如我所料,有时像素图消失(部分或完全),有时水平渐变出现在图像上(即使图像旋转它们也保持水平)。

第一张图片是一张图表(应该没有颜色渐变),上面有一个单独的网格(线条的集合)。第二张图片来自我的最小示例(下图),显示像素图部分缺失(镜头远离像素图边缘)。

以下是一个简单的示例,它演示了我所看到的大部分内容。

#ifndef VIEW_H
#define VIEW_H

#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QWheelEvent>
#include <QKeyEvent>

class View : public QGraphicsView

  Q_OBJECT
public:
  explicit View(QWidget *parent = 0) :
    QGraphicsView(parent)
  
    setDragMode(QGraphicsView::ScrollHandDrag);

    QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem(QPixmap(":/images/chart.png"));
    pixmapItem->setTransformationMode(Qt::SmoothTransformation);

    QGraphicsScene *scene = new QGraphicsScene();
    scene->addItem(pixmapItem);
    setScene(scene);
  

protected Q_SLOTS:
  void wheelEvent(QWheelEvent *event)
  
    if(event->delta() > 0)
      scale(1.25, 1.25);
    else
      scale(0.8, 0.8);
  

  void keyPressEvent(QKeyEvent *event)
  
    if(event->key() == Qt::Key_Left)
      rotate(1);
    else if(event->key() == Qt::Key_Right)
      rotate(-1);
  
;

#endif // VIEW_H

与此相关的其他文件是包含图像的资源文件、在其 ui 中保存 View 的 QMainWindow 类和执行主窗口类的 main,所有这些都在 Github project 中可用。

使用鼠标滚轮放大并使用箭头键旋转(您也可以使用鼠标平移)。如果放大到足够远并旋转,像素图将在某些角度消失(部分或完全)。在此示例中,我还无法重新创建渐变,但我怀疑它们只是同一问题的另一种表现。

我尝试将转换设置为 SmoothTransformation 并将 renderHint 设置为 Antialiasing 和 HighQualityAntialiasing,但两者都没有产生重大影响(抗锯齿确实可以在高缩放时平滑锯齿)。此外,我尝试在 QGraphicView、QGraphicsScene 相关绘图中切换许多标志。有谁知道为什么会发生这种情况或我可以尝试解决什么问题?

我在 2016 年 10 月 18 日下载的 Qt 4.8.2 和 Qt 5.5.1 中都看到了这个问题,作为 Qt 的当前稳定版本。

【问题讨论】:

原图是什么样子的? 就目前而言,虽然您有一个合理的问题,但我们只能猜测导致问题的原因。提供MCVE 将大大改善问题。 我刚刚发布了一个 MCVE,它包含了 png。 “M”代表最小。那件事应该少于 150 行代码,放在一个文件中,并包含在问题本身中。您还应该在最新的 Qt 上尝试您的代码,并检查其行为是否有所不同;然后你可以一分为二来检查它在哪里被修复了。 最新 Qt 中的相同行为。我会尽量精简我的例子。 【参考方案1】:

看来这可能与limitation of x11 有关。基本上,一旦达到足够大的缩放,就会达到最大尺寸值。

我仍然不完全确定为什么旋转似乎会影响事物,但作为一个猜想,这可能是因为它与图像的边界矩形的大小有关,它会以不同的角度变化。我看到的渐变也很奇怪,图像只是部分消失了,但似乎它们都相关,这是另一种表现形式。

【讨论】:

以上是关于在 QGraphicsScene 中缩放和旋转的 QGraphicsPixmapItem 的奇怪绘图行为的主要内容,如果未能解决你的问题,请参考以下文章

如何在 QGraphicsScene 中缩放图像? (Qt 5.11)

尽管使用了 itemsBoundingRect(),但 QGraphicsScene 和 fitInView() 无法正确缩放

缩放 QGraphicsScene 以填充整个 QGraphicsView

Qt - 如何将 QGraphicsScene 缩放到 QGraphicsView

Qt 5.10 QGraphicsView 无法将 QGraphicsScene 缩放到全屏

如何在 QGraphicsScene 中正确放置小部件