Qt:选择的项目出现在 QGraphicsScene 的顶部

Posted

技术标签:

【中文标题】Qt:选择的项目出现在 QGraphicsScene 的顶部【英文标题】:Qt: having selected items appear on top in QGraphicsScene 【发布时间】:2014-06-15 15:38:48 【问题描述】:

所以我有一个QGraphicsScene,里面有各种物品。其中一些可以在场景中采用相同的坐标。当我显示场景时,顶部显示的是最后添加的场景。有没有办法让某个项目始终出现在顶部,甚至更好地让它在程序期间重新出现在顶部(而不是删除它并再次添加它)?我一直在考虑先把所有的东西都画出来,然后用setVisible()来只显示我想要的项目,但是由于我想在网上添加新的东西,这似乎有点问题。

【问题讨论】:

【参考方案1】:

您可以使用QGraphicsItem::setZValue ( qreal z ) 设置项目的Z 值。 Z 值决定同级项的堆叠顺序。具有较高 Z 值的项目将始终绘制在具有较低 Z 值的另一个项目之上。默认 Z 值为零。因此,您可以将其设置为更高的值以将其置于首位:

item->setZValue(1);

或将其放在其他项目的底部:

item->setZValue(-1);

【讨论】:

1 是可能的最高 Z 值吗?因为如果不是 @Leslie 的答案将是正确的(尽管性能不佳)。 @rbaleksandar Z 值可能大于 1。管理 z 订单的逻辑取决于应用程序,可以通过多种方式完成。【参考方案2】:

在做了一些研究之后,我认为@Leslie 的答案比@Nejat 的答案更正确。但是,如果您有很多项目并且您必须经常进行检查,则效率非常低。

在我的情况下,我有一个 QGraphicsTextItem,它显示了我场景中光标的坐标。

void QCVN_SceneView::mouseMoveEvent(QMouseEvent *event)

  QPointF cursorPoint = mapToScene(event->pos());
//  cout << "Event pos: x=" << event->pos().x() << ", y=" << event->pos().y() << endl;
//  cout << "Event pos (in scene): x=" << cursorPoint.x() << ", y=" << cursorPoint.y() << endl;

  QString coords = QString("%1, %2")
                          .arg(cursorPoint.x())
                          .arg(cursorPoint.y());

  cursorSceneCoords->setPlainText(coords);
  cursorSceneCoords->setPos(cursorPoint);

  QGraphicsView::mouseMoveEvent(event);

显然,如果我在场景中有 10000000 个项目,使用 setZValue(1) 将无法解决问题,除非所有项目的 z-value 都低于 1。遍历整个项目列表也是一种不好的做法。

我稍微考虑了一下,当我想起setZValue() 使用qreal 参数时,我就震惊了。根据系统,它可以是doublefloat,但这并不重要。我们可以简单地使用std::numeric_limits 来获得非常非常高的价值。当然,我们必须限制场景中的所有项目(除了我们想要在顶部的所需的一次)以具有最大可能值 minus 1(或 0.1 或其他)的最大值 z-value。所以如果你这样做了

YOUR_GRAPHICS_ITEM.setZValue(std::numeric_limits<qreal>::max());

该项目将始终位于其余项目之上。

【讨论】:

【参考方案3】:

这个问题有点令人困惑。主题提到选择时想要的项目在顶部,而描述则谈论更永久的排序问题(创建等)。我添加这个答案是为了澄清由于主题而来到这里的人的可能解决方案:

对于永久订单深度管理setZValue 是要走的路。例如,具有组背景的节点视图应始终位于所有其他项目的后面,zValue 可以设置为 -100。 对于临时排序,例如选择,您不想弄乱永久排序(应为用户设置或应用程序特定的排序状态需要保留),您可以使用stackBefore。这将改变项目的顺序 在同一个 zDepth。 因此,选择项目时,您可以通过所有项目运行并调整顺序,并且您不必担心尝试重置zDepth后面完成的内容(我想你仍然想要恢复,但是至少这样,关注点与zDepth 是分开的。请注意,FWIW,我发现siblingstackBefore 排序感觉倒退了。

【讨论】:

【参考方案4】:

检查一下

http://www.qtcentre.org/threads/5428-help-with-ZValue!!

// Find largest Z
qreal maxZ = 0;
foreach (QGraphicsItem *item, 
        clickedItem>collidingItems(Qt::IntersectsItemBoundingRect))
    maxZ = qMax(maxZ, item->zValue());

// Assign new Z
clickedItem->setZValue(maxZ + some);

【讨论】:

【参考方案5】:

https://github.com/sonichy/HTYPaint2/blob/master/mainwindow.cpp#L775

void MainWindow::on_action_layerTop_triggered()

    if(scene->selectedItems().size() > 0)
        QList<QGraphicsItem*> collidingItems = scene->collidingItems(scene->selectedItems().first());
        for(int i=0; i<collidingItems.size(); i++)
            collidingItems.at(i)->stackBefore(scene->selectedItems().first());
        
        scene->update();
    

【讨论】:

以上是关于Qt:选择的项目出现在 QGraphicsScene 的顶部的主要内容,如果未能解决你的问题,请参考以下文章

安装Qt Creator后,创建项目时出现“No valid kits found”

QT添加工具栏

驾校科目一考试系统——新建项目

02——驾校科目一考试系统——新建项目

解决QT编程出现 C2001错误

在QT中怎么实现当单击QLabel时出现一个下拉菜单?并且选择一个项目后,前面打勾? 求高手帮忙!