QGraphicsItem:为什么没有`stackAfter`方法?

时间:2013-02-26 04:37:24

标签: qt pyqt4 pyside

我正在努力绕过“推荐”的做事方式。

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

这样做的推荐方法就是添加到对象的zValue,直到它比其他所有对象都大,但是我希望废除相当“懒惰”的整数,这些整数在整个地方奔跑着使用stackBefore方法,该方法模拟重新组织对象添加到场景的顺序。

当我在一个有限的集合中洗牌时这是完全正常的(获取所选项目的列表,random.shuffle,对于项目do.stackBefore(下一个项目)),但它在冒泡时肯定不起作用卡片在整个场景的顶部。

我考虑过将一个对象的副本添加到场景然后删除原始文件,但似乎我应该像使用Python列表时那样stackAfter(或{{1}或者什么)。

示例代码:

insertAt

这很有效。它看起来有点......丑陋。

1 个答案:

答案 0 :(得分:1)

self.scene.items返回堆叠顺序中的项目(link)。因此,如果您想要stackAfter项目,您只需查询当前最顶层项目的z值,然后将新最顶层卡片的z值设置为更大的值。

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

希望有所帮助。

http://gitorious.org/qt/修改stackBeforesetZValue添加的src 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();
}