treslumen
treslumen

Reputation: 182

Qt.binding in a for loop

In a TabView, I'm trying to load a list of Tab items from a string property:

TabView {
    id: tabView1
    property string tabs: "/etc,/bin"

    function loadTabs() {
        var tab_array = tabs.split(",");
        for (var i = 0; i < tab_array.length; i ++) {
            var dirTableView = Qt.createComponent("dirview.qml");

            var newTab = tabView1.addTab("", dirTableView);
            newTab.active = true;
            newTab.item.folderUrl = "file://" + tab_array[i];
            newTab.title = Qt.binding(function() {
                return newTab.item.folderUrl.toString().replace("file://", "");
            });
        }
    }
    Component.onCompleted: {
        loadTabs();
    }
}

Each Tab loads a TableView of directory content (as specified in dirview.qml).

The Tab.title binding doesn't work, because newTab gets reassigned to a different Tab in each iteration, hence the result is that all the tabs' title is bound to the title of the last tab.

I tried to use an array to store different Tab items returned by TabView.addTab():

property var tabArray: []

function loadTabs() {
    var tab_array = tabs.split(",");
    for (var i = 0; i < tab_array.length; i ++) {
        var dirTableView = Qt.createComponent("dirview.qml");
        tabArray[i] = tabView1.addTab("", dirTableView);
        tabArray[i].active = true;
        tabArray[i].item.folderUrl = "file://" + tab_array[i];
        tabArray[i].title = Qt.binding(function() {
            return tabArray[i].item.folderUrl.toString().replace("file://", "");
        });
    }
}

But that doesn't work either. Apparently Qt.binding() is triggered as soon as the array is declared, but at that time, the array is empty, hence I get the error "Cannot read property 'item' of undefined" (referring to Qt.binding()). Strangely, somehow the titles are correctly set when the application starts, but when item.folderUrl changes as I navigate around the directory tree, the title doesn't update accordingly, hence the binding isn't working.

What is the way to do Qt.binding correctly in a for loop here?

Upvotes: 1

Views: 410

Answers (1)

treslumen
treslumen

Reputation: 182

Just tried one more little thing and it worked!

function loadTabs() {
    var tab_array = tabs.split(",");
    for (var i = 0; i < tab_array.length; i ++) {
        var dirTableView = Qt.createComponent("dirview.qml");
        var newTab = tabView1.addTab("", dirTableView);
        newTab.active = true;
        newTab.item.folderUrl = "file://" + tab_array[i];
        newTab.title = Qt.binding(function() {
            return this.item.folderUrl.toString().replace("file://", "");
        });
    }
}

The only change made is that in the binding expression, newTab is replaced by this. Inspired by this.

Apparently using this eliminates the ambiguity, Qt.binding() knows exactly which newTab to refer to.

Upvotes: 1

Related Questions