2
votes

Is there a simple way to modify a row height given its index in a QML TableView ?

My problem is that I dynamically load data is the TableView's model. I have a "warnings" column in which i would like to display a list of warnings using Qt RichText HTML tags (ul, li). However, this list is higher than the cell that contains it and there is a y-overflow.

The QTableView class have many methods to solve this problem such as setRowHeight(int row, int height), resizeRowToContents(int row) or resizeRowsToContents().

But it seems that the QML equivalent does not have such methods to easily resize a row...

The rowDelegate might solve my problem but I don't know how to use it to modify the rows' heights separately (I mean given its index).

Does anyone had the same problem and could give me a trick to solve it ?

My TableView :

ListModel {
id: filesList
ListElement {
    name:""
    dir:""
    type:""
    status""
}
 }

 TableView {
id: filesTable
TableViewColumn {
    id:nameColumn
    role: "name"
    title: "Name"
    width: dropFiles.width*.2
}
TableViewColumn {
    id:dirColumn
    role: "dir"
    title: "Path"
    width: dropFiles.width*.8
}
TableViewColumn {
    id:typeColumn
    visible: false;
    role: "type"
    title: "Type"
    width: dropFiles.width*.2
}
TableViewColumn {
    id:statusColumn
    visible: false;
    role: "status"
    title: "Status"
    width: dropFiles.width*.3
}
rowDelegate: Rectangle {
    anchors {
        left: parent.left
        right: parent.right
        verticalCenter: parent.verticalCenter
    }
    height: parent.height
    MouseArea {
        anchors.fill: parent
        acceptedButtons: Qt.RightButton
        onClicked: {
            if (mouse.button == Qt.RightButton)
            {
                if(styleData.selected){
                    rowContextMenu.popup();
                }
                else {
                    filesTable.selection.deselect(0, filesTable.rowCount-1);
                    filesTable.selection.select(styleData.row);
                    rowContextMenu.popup();
                }
            }
        }
    }
}
anchors.fill: parent
selectionMode: SelectionMode.ExtendedSelection
model: filesList
 }

The JS function that update my TableView :

function displayParsingStatus(){
    for(var i= 0; i<newModel.files.length; ++i){
        switch(newModel.files[i].status){
            case 0:
                filesList.get(i).status="<font color=\"green\">Success</font>";
                break;
            case 1:
                var status ="";
                status += "<ul>";
                for(var j=0; j < newModel.files[i].warnings.length;j++){
                    status += "<li><font color=\"orange\">Warning: " + newModel.files[i].warnings[j] + "</font></li>";
                }
                status += "</ul>";
                filesList.get(i).status=status;
                break;
            case 2:
                filesList.get(i).status="<font color=\"red\"><b>Error: " + newModel.files[i].error + "</b></font>";
                break;
            case 3:
                filesList.get(i).status="Ignored";
                break;
        }
    }
}
1

1 Answers

2
votes

You're already setting the height on the QML delegate element:

height: parent.height

It's binding the height to the parent height. If you set the height with an expression, it'll be triggered (and re-evaluated) every time there's a change on any of the elements of the expression.

That's why the QML properties have a NOTIFY signal.

So if you want to bind the height to some other element you just need to assign it to the height attribute.

I haven't tried but the childrenRect may be what you're looking for: http://doc.qt.io/qt-5/qml-qtquick-item.html#childrenRect.height-prop

You can also use ternary operator to assign values to the property, i.e:

height: (model.get(styleData.row)[styleData.role] === 0)?30:100