[英]Qt: having selected items appear on top in QGraphicsScene
So i have a QGraphicsScene
with various items. 所以我有一个
QGraphicsScene
与各种项目。 Some of the can take the same coordinates in the scene. 有些可以在场景中采用相同的坐标。 When I display the scene the ones displayed on top are the ones which were added last.
当我显示场景时,在顶部显示的是最后添加的。 Is there a way to make a certain item always appear on top or even better make it reappear on top during the program (rather than deleting it and adding it again)?.
有没有一种方法可以使某个项目始终显示在顶部,甚至更好地使其在程序运行期间重新显示在顶部(而不是删除它并再次添加它)? I've been thinking about drawing everything beforehand and then using
setVisible()
to show only the items I want to, but since I want to add new things online it seems to be a bit problematic. 我一直在考虑事先绘制所有内容,然后使用
setVisible()
仅显示我想要的项目,但是由于我想在线添加新内容,因此似乎有点问题。
You can use QGraphicsItem::setZValue ( qreal z )
to set the Z-value of the item. 您可以使用
QGraphicsItem::setZValue ( qreal z )
设置项目的Z值。 The Z value decides the stacking order of sibling items. Z值决定兄弟项目的堆叠顺序。 An item with a higher Z value will always be drawn on top of another item with a lower Z value.
Z值较高的项目将始终绘制在Z值较低的另一个项目的顶部。 The default Z value is zero.
Z的默认值为零。 So you can set it to a higher value to bring it on top :
因此,您可以将其设置为更高的值以使其位于最上方:
item->setZValue(1);
or bring it to bottom of other items : 或将其置于其他项目的底部:
item->setZValue(-1);
After doing some research I think that @Leslie 's answer is in a way more correct than @Nejat 's. 经过研究后,我认为@Leslie的答案比@Nejat的答案更正确。 However it is very inefficient if you have a lot of items and you have to do that check very often.
但是,如果您有很多物品,并且必须经常进行检查,则效率很低。
I my case I have a QGraphicsTextItem
that shows the coordinates of the cursor inside my scene. 以我
QGraphicsTextItem
,我有一个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);
}
Obviously if I have 10000000 items in the scene using setZValue(1)
will not do the trick unless all items are with a z-value
under 1. Iterating through the whole list of items is also a bad way of doing it. 显然,如果我在场景中有1000万个项目,则除非所有项目的
z-value
在1以下,否则使用setZValue(1)
不会达到目的,遍历整个项目列表也是一种不好的方法。
I gave it a little thought and it struck me once I remembered that setZValue()
uses a qreal
argument. 我想了一下,当我想起
setZValue()
使用qreal
参数时,它就使我qreal
。 Depending on the system it can be a double
or a float
however this is not important. 根据系统的不同,它可以是
double
或float
但这并不重要。 We can simply use std::numeric_limits
to get the very, very top value possible. 我们可以简单地使用
std::numeric_limits
来获得非常非常高的值。 Of course we have to limit all our items in the scene (except the desired once that we want on top) to have a maximum z-value
of maximum possible value minus 1 (or 0.1 or whatever). 当然,我们必须限制场景中的所有项目(除了我们想要在顶部想要的一次),最大
z-value
为最大可能值减去 1(或0.1或其他值)。 So if you do 所以如果你这样做
YOUR_GRAPHICS_ITEM.setZValue(std::numeric_limits<qreal>::max());
the item will always be on top of the rest. 该项目将始终位于其余项目之上。
Check this 检查一下
http://www.qtcentre.org/threads/5428-help-with-ZValue!! 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);
This question is a little confusing. 这个问题有点令人困惑。 The subject mentions wanting items on top when selected, while the description talks about more permanent ordering concerns (creation and such).
当选择主题时,主题会提到想要的物品在最上面,而描述中谈到的是更持久的订购问题(创作等)。 I'm adding this answer to clarify possible solutions for those coming here due to the subject:
我正在添加此答案,以阐明针对此主题而来的解决方案:
zValue
can be set to -100. zValue
可以设置为-100。 zDepth
. zDepth
的项目顺序 。 So, when items are selected you could run through all items and adjust the order and you don't have to worry about trying to reset zDepth
back to what it was before when done (I suppose you could still want to restore, but at least this way the concerns are separate from zDepth
). zDepth
重置为完成后的状态(我想您仍然可以恢复,但至少这样,关注点便与zDepth
分离了)。 Note, FWIW, I find the stackBefore
ordering of sibling
to feel backwards. sibling
排序之前先找到了stackBefore
,以使其感到向后。 https://github.com/sonichy/HTYPaint2/blob/master/mainwindow.cpp#L775 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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.