TableView & Dynamic columns creation



  • Hello Friends.

    I have a doubt regarding dynamic objects creation for a QML TableView ( QtQuick Controls)
    Is it possible to insert a new column on TableView?
    Documentation describes that it has to be an instance of TableViewColumn, but for my application the ListModel changes in runtime so the TableView should do so as well.

    It seems that the model is not visible to the created object, so the column is added but empty.

    Thanks.

    Here is a code example:

    @
    TableView{
    id:idTable
    x: 50
    y: 50
    width: 400
    model: libraryModel // Table Data model

        TableViewColumn{ role: "title"  ; title: "Title" ; width: 100 }
        TableViewColumn{ role: "author" ; title: "Author" ; width: 200 }
        property string strTestColumn : "import QtQuick 2.1; import QtQuick.Controls 1.0; import QtQuick.Layouts 1.0; TableViewColumn{id:idTestColumn; role:\"buyer\"; title: \"Another Column\" ; width: 100 ; Component.onCompleted: {console.log(\"#\");libraryModel.count}}"
    
        Component.onCompleted: {
    
            var ii= 0
    
            //it starts at zero "0"
            for( ii=0; ii < libraryModel.count;ii++)
            {
                libraryModel.setProperty(ii, "buyer", "Something");
                console.log(libraryModel.get(ii).buyer + "\n");
            }
            idTable.addColumn(Qt.createQmlObject(idTable.strTestColumn,idTable,'firstObject'));
        }
    
    }
    
    
    //Data model for Table
    ListModel {
       id: libraryModel
       //syntax: ListElement{ <Key identifier>: <Value>; ... }
       ListElement{ title: "A Masterpiece" ; author: "Gabriel" ; pages: 500; mc: "1"}
       ListElement{ title: "Brilliance"    ; author: "Jens"    ; pages: 700; mc: "2"}
       ListElement{ title: "Outstanding"   ; author: "Frederik"; pages: 600; mc: "3"}
    }@


  • It seems the column data will show up only if the original model has at least one reference to the new value (i.e add a single "buyer" entry in the original model and it will show). I suspect ListModel caches the initial roleNames only at startup and never updates the roles that are added later. This would cause such issues in both TableView and ListView.

    So in short this does not seem to be a supported use case at the moment. I would suggest you file a bug report for this. The workaround for now would be to ensure that you add at least dummy/empty properties for all the roles you are going to add/use later.



  • Thanks for your hints.

    I would like to comment that I modified the onCompleted() method as follows and seems to work but I do not like to use an additional empty ListModel as a buffer.
    @
    ListModel
    {
    id: tempModel
    }
    ...
    Component.onCompleted: {
    idTable.addColumn(Qt.createQmlObject(idTable.strTestColumn,idTable,'firstObject'))

            var ii= 0
    
            //it starts at zero "0"
            for( ii=0; ii < libraryModel.count;ii++)
            {
                libraryModel.setProperty(ii, "buyer", "Counter");
                console.log(libraryModel.get(ii).buyer + "\n");
            }
    
            for( ii=0; ii < libraryModel.count;ii++)
            {
                tempModel.append(libraryModel.get(ii));
            }
    
            idTable.model=tempModel;
    
        }@


  • Actually you do not have to. It turns out this is already supported but you simply need to enable it on ListModel itself by setting the "dynamiRoles" property.

    The only difference code wise is that it means you cannot initially declare any items in the ListModel. However just replace the original data in an onCompleted and you are set:

    @
    Rectangle {
    width: 1000
    height: 800

    TableView{
        id:idTable
        x: 50
        y: 50
        width: 400
        model: libraryModel                             // Table Data model
    
        TableViewColumn{ role: "title"  ; title: "Title" ; width: 100 }
        TableViewColumn{ role: "author" ; title: "Author" ; width: 200 }
        property string strTestColumn : "import QtQuick 2.1; import QtQuick.Controls 1.0; import QtQuick.Layouts 1.0; TableViewColumn{id:idTestColumn; role:\"buyer\"; title: \"Another Column\" ; width: 100 ; Component.onCompleted: {console.log(\"#\");libraryModel.count}}"
    
        Component.onCompleted: {
    
            var ii= 0
    
            //it starts at zero "0"
            for( ii=0; ii < libraryModel.count;ii++)
            {
                  libraryModel.setProperty(ii, "buyer", "Something");
                console.log(libraryModel.get(ii).buyer + "\n");
            }
            idTable.addColumn(Qt.createQmlObject(idTable.strTestColumn,idTable,'firstObject'));
        }
    
    }
    
    //Data model for Table
    ListModel {
        id: libraryModel
        dynamicRoles: true
        Component.onCompleted: {
            append({title: "A Masterpiece" , author: "Gabriel" , pages: 500, mc: "1"})
            append({title: "Brilliance"    , author: "Jens"    , pages: 700, mc: "2"})
            append({title: "Outstanding"   , author: "Frederik", pages: 600, mc: "3"})
        }
    }
    

    }
    @



  • Thanks for the hint. I´ll test it.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.