Search code examples
c++qtqmltableviewqabstracttablemodel

QML TableView from file


Good morning,

I have some problems to create a tableview from file.

Basically I just have a Button to load csv files and I want to show the files in a QML TableView...

I think my main problem is that I have a dynamic number of columns.

TableView
{
    id: tableView

    enabled:                dynVars.csvVarTableModel.b_csvEnabled
    frameVisible:           false
    sortIndicatorVisible:   false

    model:                  dynVars.csvVarTableModel

    resources:
    {
        var roleList = dynVars.csvVarTableModel.roleStringList
        var temp = []
        for(var i=0; i<roleList.length; i++)
        {
            var role  = roleList[i]
            temp.push(columnComponent.createObject(tableView, { "role": role, "title": role}))}
            return temp
        }
    }    
}

columnComponent is just a simple TableViewColumn... I worked with the QAbstractTableModel. And i have done all the basic stuff so far i reimplemented the following funtions:

public:
        int         rowCount    (const QModelIndex &parent = QModelIndex()) const;
        int         columnCount (const QModelIndex &parent = QModelIndex()) const;
       // QVariant    headerData(int section, Qt::Orientation orientation, int role) const;
        QVariant    data(const QModelIndex & index, int role = Qt::DisplayRole) const;
    private:
        QHash<int, QByteArray> roleNames() const;

I tried to overload the roleNames function so that I have a role for every Column. That's how i understood the documentation...

QHash<int,QByteArray> CSVVarTableModel::roleNames() const
{
    QHash<int, QByteArray> roles = QAbstractTableModel::roleNames();
    for(int i = 0; i < m_v_headers.size();i++)
        roles[i + Qt::UserRole] = m_v_headers.at(i).toLatin1();
    return roles;
}

in data() I simply return m_vv_table.at(index.row()).at(role); if the role is one of the UserRoles....

This works fine for the first csv file I load to the table... But after that, when I want to load anotherfile it seems that the roleNames are not updated in the QML. I already tried several combinations to fix the problem... that's also the reason why i don't have a good Code example at the moment, it's all a bit mixed up...

I'm probably on the completely wrong way I can't imagine that it's so complicated to load some simple files.... that's making me crazy

It would be awesome if someone just give hint or a small example, how to load a file with dynamic amount of colums.

kind regards,

Moe


Solution

  • You can dynamically add columns on model change event.

    Example from my project:

                onModelChanged: {
                for(var index = tableView.columnCount-1; index>=0; index--) {
                    tableView.removeColumn(index)
                }
                for(var i = 0; i< model.columnCount(); i++) {
                    tableView.addColumn(columnComponent.createObject(
                        {                                                                        
                            "title":model.headerData(i, 1).toString(),                                                                       
                            "role":model.headerData(i, 1).toString(),                                                                        
                            "delegate": textDelegate,
                            "movable": false
                        })
                    )
                }
    
            }
    

    All other information about using c++ model in qml is in Qt documentation.