2013-02-26 83 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

相關問題