2013-02-26 84 views
0

我有一个恼人的时间试图绕过'推荐'做某事的方式。QGraphicsItem:为什么没有`stackAfter`方法?

所以,我有一堆卡。我想要这样做,以便在处理卡片时,它成为整个场景中最后绘制的对象(典型的bring_to_front功能)。

推荐的方法是只添加到对象的zValue,直到它比所有其他的都大,但我希望取消相当“懒惰”的整数,在整个地方运行,明智地使用stackBefore方法,该方法模拟重新组织对象添加到场景的顺序。

当我在一个有限的集合中刷洗我的卡片时(获得所选项目的列表,random.shuffle,对于item item.stackBefore(下一个项目)),这个工作方式非常好,但当它涉及到将卡冒泡到整个场景的顶部。

我认为添加对象的副本到场景,然后删除原来的,但它看起来像我应该能够做stackAfter像使用Python列表(或insertAt什么的)。

示例代码:

def deal_items(self): 
    if not self.selection_is_stack(): 
     self.statusBar().showMessage("You must deal from a stack") 
     return 

    item_list = self.scene.sorted_selection() 
    for i,item in enumerate(item_list[::-1]): 
     width = item.boundingRect().width() 
     item.moveBy(width+i*width*0.6,0) 

     another_list = self.scene.items()[::-1] 
     idx = another_list.index(item) 
     for another_item in another_list[idx+1:]: 
     another_item.stackBefore(item) 

这工作。这似乎有点......丑陋。

+0

也许有像'setZValue = 0'自动将对象在与zValue == 0所有对象的最终一招?我不知道 – RodericDay 2013-02-26 05:09:23

回答

1

self.scene.items返回堆叠顺序中的项目(link)。所以如果你想stackAfter一个项目,你可以查询当前最上面的项目的z值,然后将新的最上面的卡片的z值设置为一个更大的值。

item.setZValue(self.scene.items().first().zValue() + 1)

希望有所帮助。

编辑添加Src在stackBeforesetZValuehttp://gitorious.org/qt/ src/gui/graphicsview/qgraphicsitem.cpp

void QGraphicsItem::stackBefore(const QGraphicsItem *sibling) 
{ 
    if (sibling == this) 
     return; 
    if (!sibling || d_ptr->parent != sibling->parentItem()) { 
     qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling); 
     return; 
    } 
    QList<QGraphicsItem *> *siblings = d_ptr->parent 
             ? &d_ptr->parent->d_ptr->children 
             : (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : 0); 
    if (!siblings) { 
     qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling); 
     return; 
    } 

    // First, make sure that the sibling indexes have no holes. This also 
    // marks the children list for sorting. 
    if (d_ptr->parent) 
     d_ptr->parent->d_ptr->ensureSequentialSiblingIndex(); 
    else 
     d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes(); 

    // Only move items with the same Z value, and that need moving. 
    int siblingIndex = sibling->d_ptr->siblingIndex; 
    int myIndex = d_ptr->siblingIndex; 
    if (myIndex >= siblingIndex) { 
     siblings->move(myIndex, siblingIndex); 
     // Fixup the insertion ordering. 
     for (int i = 0; i < siblings->size(); ++i) { 
      int &index = siblings->at(i)->d_ptr->siblingIndex; 
      if (i != siblingIndex && index >= siblingIndex && index <= myIndex) 
       ++index; 
     } 
     d_ptr->siblingIndex = siblingIndex; 
     for (int i = 0; i < siblings->size(); ++i) { 
      int &index = siblings->at(i)->d_ptr->siblingIndex; 
      if (i != siblingIndex && index >= siblingIndex && index <= myIndex) 
       siblings->at(i)->d_ptr->siblingOrderChange(); 
     } 
     d_ptr->siblingOrderChange(); 
    } 
} 

void QGraphicsItem::setZValue(qreal z) 
{ 
    const QVariant newZVariant(itemChange(ItemZValueChange, z)); 
    qreal newZ = newZVariant.toReal(); 
    if (newZ == d_ptr->z) 
     return; 

    if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) { 
     // Z Value has changed, we have to notify the index. 
     d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ); 
    } 

    d_ptr->z = newZ; 
    if (d_ptr->parent) 
     d_ptr->parent->d_ptr->needSortChildren = 1; 
    else if (d_ptr->scene) 
     d_ptr->scene->d_func()->needSortTopLevelItems = 1; 

    if (d_ptr->scene) 
     d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true); 

    itemChange(ItemZValueHasChanged, newZVariant); 

    if (d_ptr->flags & ItemNegativeZStacksBehindParent) 
     setFlag(QGraphicsItem::ItemStacksBehindParent, z < qreal(0.0)); 

    if (d_ptr->isObject) 
     emit static_cast<QGraphicsObject *>(this)->zChanged(); 
} 
+0

它(我喜欢''第一次'调用,以前没有见过),但我只是想使用zValues完全不同。我考虑过让dz = 0.000001,所以我不必担心违反了障碍,但是我必须跟踪它并每隔一段时间重新设置一次值... idk,我只是想让它从价值中挤出更多的价值stackBefore尽可能。 – RodericDay 2013-02-26 05:26:32

+0

如果您需要另一个“z”变量,则可以对该项目进行子类化并添加它。如果您之前读过堆栈文件,它所做的只是根据另一个对象的z值编辑z值。 http://qt-project.org/doc/qt-4.8/qgraphicsitem.html#stackBefore祝你好运。 – phyatt 2013-02-26 05:35:52

+0

http://qt-project.org/doc/qt-4.8/qgraphicsitem.html#sorting也谈到了使用父母来分组和排序项目('ItemStacksBehindParent')。 – phyatt 2013-02-26 05:38:56

相关问题