固定大小的QGraphicsItem在多个视图中?

时间:2013-11-21 15:33:17

标签: c++ qt qgraphicsview

我正在使用Qt的图形视图框架可视化图形。它看起来像这样:

Example view from the program

现在,我希望顶点的大小(我绘制为小圆圈)相对于视图的缩放保持不变。目前我通过不将我的顶点作为场景中的项目来完成此操作,而是在视图的drawForeground(...)函数中绘制它们,如下所示:

void View::drawForeground(QPainter *painter, const QRectF& rect) {
    painter->setMatrixEnabled(false);
    painter->setPen(Qt::NoPen);
    painter->setBrush(Qt::black);
    painter->setRenderHint(QPainter::Antialiasing);

    // Draw points.
    const QRectF biggerRect = rect.adjusted(-100, -100, 100, 100);
    const float radius = 2.0;
    foreach (const QPointF& point, m_points) {
        if (biggerRect.contains(point)) {
            painter->drawEllipse(QPointF(mapFromScene(point)), radius, radius);
        }
    }

    // ...
}

但这是错误的,因为顶点在概念上是我场景的一部分,应该是我QGraphicsScene中的项目。另外,作为一个例子,我可能想暂时隐藏一组顶点,或者转换它们,如果它们是场景中的正确项目,这将更容易做到。最后但并非最不重要的一点是,让视图绘制点可以打破模型/视图分离并强制视图了解它们正在显示的点(可能有多个视图)。

使用这种方法我也遇到了render(...)视图QSvgGenerator时顶点(非项)和边(项)的相对位置出错的问题,可能是由于我禁止画家转型的伎俩。

所以,我的问题是:在显示场景的每个视图中,如何将我的顶点QGraphicsItem添加到我的场景中,同时仍然使其大小相对于视图保持不变?

我已尝试在项目上设置QGraphicsItem::ItemIgnoresTransformations标记。文档中有关于标志的说法:

  

该项忽略继承的变换(即,其位置仍锚定到其父级,但忽略父级或视图旋转,缩放或剪切变换)。此标志对于使文本标签项保持水平和未缩放非常有用,因此如果转换视图,它们仍然可读。设置后,将单独维护项目的视图几何和场景几何。您必须调用deviceTransform()来映射坐标并检测视图中的碰撞。默认情况下,禁用此标志。这个标志是在Qt 4.3中引入的。

但是设置此标志会导致忽略所有视图转换,这样当我放大时,点将不再显得更远,这不是我想要的。我只希望项目大小(屏幕上的像素)保持不变。

因为Merlin069要求这样做:我尝试这个标志时使用的代码只是将每个顶点添加到我的场景中,如下所示:

QGraphicsEllipseItem *item = scene->addEllipse(x - 2.0, y - 2.0, 4.0, 4.0);
item->setPen(Qt::NoPen);
item->setBrush(Qt::black);
item->setFlag(QGraphicsItem::ItemIgnoresTransformations);

下面是我所获得的截图。缩放2x,4x,8x项目大小保持不变(yay),但点之间的屏幕距离也是如此:(

Another screenshot

对此解决方案的任何提示/指示都非常感谢!

2 个答案:

答案 0 :(得分:2)

如果您查看addEllipse的文档,请说明: -

  

创建椭圆项并将其添加到场景中,并返回项指针。椭圆的几何形状由rect定义,其笔和画笔初始化为笔和画笔。

     

请注意,项目的几何图形以项目坐标提供,其位置初始化为(0,0)。

所以你在这里做的是将所有项目放在(0,0),但项目的行为正在改变。你需要做的是创建项目,然后设置他们的位置。

答案 1 :(得分:0)

QGraphicsItem::setFlag(QGraphicsItem::ItemIgnoresTransformations,true);

这应该可以解决问题。