如何在不缩放场景的情况下与 QGraphicsView 左侧的矩形对齐?

Posted

技术标签:

【中文标题】如何在不缩放场景的情况下与 QGraphicsView 左侧的矩形对齐?【英文标题】:How to align to the a rectangle to the left of a QGraphicsView without scaling the scene? 【发布时间】:2016-06-10 12:46:40 【问题描述】:

这就是我想做的。

我需要在 QGraphicsView 中绘制一系列左右对齐的矩形。我的意思是,如果矩形 i 具有位置 (0,y),矩形 i+1 需要具有位置 (0,max),其中 max 使得矩形的右侧“接触”QGraphicsView 的右侧。

调整窗口大小时,我需要重新计算 max 的值,以使矩形始终接触屏幕的右侧。

这是我添加场景的方法(这引用了一个继承 QGraphicsView 的类)

scene = new QGraphicsScene(this);
this->setScene(scene);
this->setAlignment(Qt::AlignTop|Qt::AlignLeft);

要添加一个接触左边框的矩形,我将其添加为 (0,yvalue,width,height)。

如何计算 X 的值以使矩形接触右边框?

【问题讨论】:

你会使用 QML 吗?我最近从 QGraphicsView 切换到 QML 来绘制这样的东西,对生产力的影响是巨大的。 我什至不知道 QML 是什么……说实话。我正在使用 Qt 5.1.1。那里有吗?兼容性怎么样?我更关心这一点而不是性能...... 哦,那你会喜欢的:doc.qt.io/qt-5/qmlapplications.html 兼容性很好。我在 3 个桌面平台上发布 QML 应用程序,但我使用 Qt 5.6 来执行此操作。我无法告诉你与 Qt 5.1.1 的兼容性故事。 这似乎是为了设计界面。我要做的是动态地生成这些矩形。这个也可以吗? 您需要将矩形映射到场景,并获取边界矩形的 right() 坐标。我将在 amin 中发布一个小示例。 【参考方案1】:

好的。所以这应该出现在 QGraphicsView 的 resize 事件中。但这正是我想要的:

void AView::resized()

    scene->clear();
    QSize newsize = this->size();

    qreal w = newsize.width()*.99;
    qreal h = newsize.height()*.99;
    this->setSceneRect(0,0,w,h);
    scene->setSceneRect(0,0,w,h);

    qreal rectwidth = 100;
    qreal newx = w - rectwidth;
    left = new QGraphicsRectItem(0,0,rectwidth,100);
    left->setBrush(QBrush(Qt::red));
    right = new QGraphicsRectItem(newx,100,rectwidth,100);
    right->setBrush(QColor(Qt::blue));

    scene->addItem(left);
    scene->addItem(right);


这样,蓝色矩形几乎总是在边界处。此外,没有拉伸图像。由于窗口调整大小,右边框之间存在间隙,但似乎 this->size() 返回的大小略大于您在屏幕上看到的“白色区域”。从我的实验中添加 .99 可以得到更好的结果。

【讨论】:

如果您想在每次调整大小时添加新项目,这很有效 - 您可能想先删除旧项目?看起来很辛苦:-) 如果你只是在你的左右项目上 setRect() 会更简单(并避免内存泄漏) 这只是我想做的更复杂的事情的一个例子。是的,我想避免在每次调整大小时创建项目。但这有效。问题是场景->清除实际上删除了这些项目(如果它只是将它们从场景中删除,我更愿意,但是唉......)所以如果我做一个清晰的场景,我确实需要每次都重新创建它们...... 您希望“清除”做什么?而且 - 除非你只是在你的项目上设置一个矩形,否则每次调用这个函数时你的程序都会使用越来越多的内存,最终会崩溃 - 这就是内存泄漏的意思。 我希望 clear 不会删除这些项目,而只是将它们从场景中删除。如果项目被删除,据我所知,这意味着它们占用的内存被释放。对?否则,我问你,删除是什么意思?我理解错了吗?因为如果我想知道?【参考方案2】:

这个小例子应该计算移位并根据您希望的对齐方式从选择或项目列表中移动所有项目(我显示正确,但让、中心、顶部、底部是相同的)。

QRectF refRect = scene()->sceneRect();
QList<QGraphicsItem*> sel = allItemsYouWantAligned;  // scene()->selectedItems();  for example

foreach(QGraphicsItem* selItem, sel)

    qreal dx = 0, dy = 0;
    QRectF itemRect = selItem->mapToScene(selItem->boundingRect()).boundingRect();
    if(align_right)
        dx = refRect.right() - itemRect.right();
    else
        .. calculate either dx or dy on how you want to align
    selItem->moveBy(dx, dy);

重新阅读问题 - 我发现您实际上并不需要移动矩形,而是创建新的越来越大的矩形。

您的解决方案很简单。如果您想调整大小而不是移动 - 你必须在你的物品上setRect() dx 增量:

QRectF r = selItem->rect();
r.setWidth(r.width + dx);
selItem->setRect(r);

【讨论】:

@aarelovich - 奇怪,如果你的画布和项目的 right() 边已经相同,它只能为 0。 我会再试一次(我用我所做的所有修改删除了代码)然后回来查看....

以上是关于如何在不缩放场景的情况下与 QGraphicsView 左侧的矩形对齐?的主要内容,如果未能解决你的问题,请参考以下文章

在不破坏管道的情况下与进程多次通信?

在不激活表单的情况下与表单交互

是否可以在不锁定的情况下与 NamespaceProxy 和 BaseManager 共享复杂对象?

如何在不实际缩放的情况下更改视图缩放值?

如何在不更改用户设置的缩放比例的情况下更新地图标记?

如何在不缩放图像子视图的情况下缩放图像?迅速的ios