Как заменить () элемент в Qml StackView, который не находится на вершине стека?

Согласно документам Qt я должен быть в состоянии позвонить:

Замена элемента(цель, элемент, свойства, операция)

Заменяет один или несколько элементов в стеке указанным элементом и операцией и дополнительно применяет к элементу набор свойств. Элемент может быть элементом, компонентом или URL-адресом. Возвращает элемент, который стал текущим.

Итак, если бы я должен был принять:

stackView.replace(stackView.get(stackView.depth - 3), mycomponent)

Я бы ожидал, что элемент, расположенный в индексе stackView на 2 меньше самого большого индекса, заменит на mycomponent. Однако, это не так; кажется, что индексы depth - 1 и depth - 2 и depth - 3 извлекаются из стека, затем добавляется экземпляр mycomponent. Как заменить индекс depth - 3 без потери объектов с более высоким стеком?

MVP: в следующем коде, если я push, push, push, а затем replace, я ожидаю, что Depth at onCompleted: 4 будет значением для Current Index: 1. Вместо этого я получаю Depth at onCompleted: 2

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2

Window {
    visible: true
    width: 640
    height: 480
    id: window

    Component {
        id: mycomponent
        Row {
            spacing: 2
            Button {
                text: "Push"
                onClicked: push(mycomponent)
            }
            Button {
                text: "Pop"
                onClicked: pop()
            }
            Button {
                text: "Replace"
                onClicked: stackView.replace(stackView.get(stackView.depth - 3), mycomponent)
            }
            Text {
                text: "Current Index: " + (stackView.depth - 1)
            }
            Text {
                Component.onCompleted: text = "Depth at onCompleted: " + stackView.depth
            }
        }
    }

    StackView {
        id: stackView
        initialItem: mycomponent
    }
}

person Tyler M    schedule 18.02.2020    source источник


Ответы (1)


Не то, чтобы описанное поведение правильно задокументировано (второе абзац):

Если аргумент target указан, все элементы до элемента будут заменены. Если цель равна нулю, все элементы в стеке будут заменены. Если не указано, будет заменен только верхний элемент.

Решение может состоять в том, чтобы сначала вытолкнуть 3 элемента (и сохранить два верхних элемента), отправить новый компонент и, в конце, нажать сохраненные элементы:

...
Button {
    text: "Replace"
    onClicked: {
        var item1 = stackView.pop();
        var item2 = stackView.pop();
        stackView.pop();
        stackView.push(mycomponent);
        stackView.push(item2);
        stackView.push(item1);            
    }
}
...
person m7913d    schedule 18.02.2020
comment
Спасибо, что поймали это. Жаль, что нет встроенного способа сделать это, но мне просто достаточно - person Tyler M; 18.02.2020
comment
@TylerM Операция, которую вы хотите, не является поведением стека (представления). Несколько странно, что вы хотите изменить элемент не верхнего уровня, поскольку он представляет собой предыдущий кадр (к которому обычно можно получить доступ с помощью функции возврата). Обратите внимание, что вы можете расширить StackView своей пользовательской функцией замены по желанию. - person m7913d; 18.02.2020