Reputation: 99
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;
}
}
}
Upvotes: 2
Views: 3218
Reputation: 5322
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
Upvotes: 2