Tyler M
Tyler M

Reputation: 412

How to replace() an item in Qml StackView that is not on the top of the stack?

According to the Qt docs I should be able to call:

Item replace(target, item, properties, operation)

Replaces one or more items on the stack with the specified item and operation, and optionally applies a set of properties on the item. The item can be an Item, Component, or a url. Returns the item that became current.

So if I were to enact:

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

I would expect the item, located at the stackView index 2 less than the largest index, to replace with mycomponent. However, this is not the case; it seems that index depth - 1 and depth - 2 and depth - 3 are popped off the stack, then an instance of mycomponent is added. How do I replace index of depth - 3 without losing the higher-stacked objects?

MVP: In the following code, if I push, push, push, then replace, I would expect Depth at onCompleted: 4 to be the value for Current Index: 1. Instead, I get 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
    }
}

Upvotes: 0

Views: 1805

Answers (1)

m7913d
m7913d

Reputation: 11064

Not that the described behaviour is correctly documented (second paragraph):

If the target argument is specified, all items down to the item will be replaced. If target is null, all items in the stack will be replaced. If not specified, only the top item will be replaced.

A solution may be to first pop 3 items (and store the two top items), push your new component and at the end push the stored items:

...
Button {
    text: "Replace"
    onClicked: {
        var item1 = stackView.pop();
        var item2 = stackView.pop();
        stackView.pop();
        stackView.push(mycomponent);
        stackView.push(item2);
        stackView.push(item1);            
    }
}
...

Upvotes: 1

Related Questions