Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Seeking workaround for TableView contentX|contentY bug when hiding columns



  • I found a rather serious bug where TableView.contentX and TableView.contentY gets corrupted when you hide and reshow columns or rows (bug report here). I'm looking for a workaround since this makes it impossible to use overlay items.

    More specifically, resizing the width of a TableView with columnWidthProvider results in the contentX property having the wrong value. The following video demonstrate how the red rectangle, which has a fixed x of zero, jumps to the right as you resize the TableView:

    https://youtu.be/9YEaoTUR4Eo

    import QtQuick 2.14
    import QtQml.Models 2.14
    import Qt.labs.qmlmodels 1.0
    
    
    TableView {
        id: table        
    
        Timer {
            // Just resize the table twice on init to programatically reproduce the bug.
            // comment this entire item out to reproduce the bug with manual window resizing.
            id: timer
            interval: 1
            running: true
            repeat: true
            property int count: 0
            onTriggered: {
                if(count == 0){
                    table.width = 400
                } else if(count == 2) {
                    timer.running = false
                }
                count++
            }
        }
    
        // This "overlay" element doesn't stay put as it should since `x` is always zero.
        // https://doc.qt.io/qt-5/qml-qtquick-tableview.html#overlays-and-underlays
        Rectangle {
            width: 20
            height: table.contentHeight
            color: 'red'
        }
    
        onWidthChanged: {
            table.forceLayout()
            print('contentX', contentX) // shows that contextX does not match what is displayed.
        }
    
        // Bug happens when a zero-width column changes to a positive-width column.
        // So expand the table from less than 200 width to greater than 200 width to corrupt contentX.
        columnWidthProvider: function(col) {
            if(table.width > 200) {
                return 40
            } else {
                return col % 2 == 0 ? 0 : 60 // change the `0` width to `1` and the bug doesn't happen
            }
        }
    
        delegate: Rectangle {
            implicitHeight: 30
            border {
                width: 1
            }
            Text { text: display }
        }
    
        model: TableModel {
            TableModelColumn { display: 'col_1' }
            TableModelColumn { display: 'col_2' }
            rows: [
                { col_1: 'cell 1', col_2: 'cell 1' },
            ]
        }
    }
    


  • For what it's worth, emitting modelReset from the model does seem to reset the corruption, but then you loose any view state, scroll positions, etc.


Log in to reply