c – 多个视图中固定大小的QGraphicsItems?

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

现在,我希望顶点的大小(我绘制为小圆圈)相对于视图的缩放保持不变.目前我没有将我的顶点作为场景中的项目来实现这一点,而是在视图的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中的项目.另外,作为一个例子,我可能想暂时隐藏一组顶点,或者转换它们,如果它们是场景中的正确项目,这将更容易做到.最后但并非最不重要的是,让视图绘制点可以打破模型/视图分离并强制视图了解它们正在显示的点(可能有多个视图).

使用这种方法我也遇到了顶点(非项)和边(项)的相对位置的问题,这些位置在向QSvgGenerator渲染(…)时出现错误,可能是由于我禁止转换的技巧画家.

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

我试过在项目上设置QGraphicsItem::ItemIgnoresTransformations标志.文档有关于标志的说法:

The item ignores inherited transformations (i.e., its position is still anchored to its parent, but the parent or view rotation, zoom or shear transformations are ignored). This flag is useful for keeping text label items horizontal and unscaled, so they will still be readable if the view is transformed. When set, the item’s view geometry and scene geometry will be maintained separately. You must call deviceTransform() to map coordinates and detect collisions in the view. By default, this flag is disabled. This flag was introduced in 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),但点之间的屏幕距离也是如此:(

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

最佳答案 如果你看一下addEllipse的文档,它说:

Creates and adds an ellipse item to the scene, and returns the item pointer. The geometry of the ellipse is defined by rect, and its pen and brush are initialized to pen and brush.

Note that the item’s geometry is provided in item coordinates, and its position is initialized to (0, 0).

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

点赞