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

QTableView/QAbstractItemModel: Spanned rows are not displayed correctly when a column from outside of the visible area is moved to the beginning.



  • Hi all!

    I have a problem with QTableView and QAbstractItemModel modules. I've tried some different workarounds and still nothing, so I've decided to ask for help here.

    I have a simple application for test purposes only. The application has a table (25x25) and horizontal/vertical scroll bars. Two rows are merged by the'setSpan' command. The app uses my own model that inherits from QAbstractItemModel. The model has its own 'data' method that allows me to still have a correctly displayed row spand even if columns will be moved. However, if I scroll to right and then move any column to the first place, the row span is not displayed correctly. I don't understand why it does not work in this case.

    This is how the table looks at the beginning (Sorry for these checkboxes, they have been added by default)
    Capture0.PNG

    This is a correct result after moving column '3' to the beginning.
    Capture1.PNG

    This is what happened to rows 3 and 4 after column 10 has been moved.
    Capture2.PNG

    My code.

    QVariant MyModel::data(const QModelIndex &index, int role) const
    {
        Q_UNUSED(role)
        return !isRowSpanned(index.row())
                ? QString("%1/%2").arg(index.column()).arg(index.row())
                : index.column() == _firstColumn
                  ? "Text"
                  : QVariant();
    }
    //_firstColumn is 0 by default
    
    void MyModel::setFirstColumn(int column)
    {
        _firstColumn = column;
    }
    

    This is the method that should fix spanned row. I'm checking which column is first. Then, the old span is removed and I set a new one. This is working perfectly until I'm moving columns that are in the visible area. When I scroll to the right, it does not set the span properly. I've also checked that columnSpan() return correct information.

    void MainWindow::on_pushButton_clicked()
    {
        int columnCount = myModel->columnCount(QModelIndex());
        int rowCount = myModel->rowCount(QModelIndex());
    
        int newIndex = 0;
        for (int i = 0; i < columnCount; i++)
            if (ui->tableView->horizontalHeader()->sectionPosition(i) == 0)
                newIndex = i;
    
        for (int row = 0; row < rowCount; row++)
        {
            if (myModel->isRowSpanned(row))
            {
                qint8 nFirstColumn = myModel->getFirstColumn();
                ui->tableView->setSpan(row, nFirstColumn, 1, 1);
                ui->tableView->setSpan(row, newIndex, 1, columnCount);
            }
        }
        myModel->setFirstColumn(newIndex);
    }
    

    Is it a Qt bug or I have to implement my own 'setSpan' method for my model? I've also found a similar ticket (QTBUG-46464) that has been not fixed and closed. I have this issue in Qt5.12.3.


  • Lifetime Qt Champion

    spanning only works correct when the columns are not moved. Once they're moved I don't see a way how a span should work at all.



  • @Christian-Ehrlicher said in QTableView/QAbstractItemModel: Spanned rows are not displayed correctly when a column from outside of the visible area is moved to the beginning.:

    spanning only works correct when the columns are not moved. Once they're moved I don't see a way how a span should work at all.

    Well, so why does spanning works correctly when columns 2-7 are moved, but it does not work when I scroll to the right and will take column number 20 (for example) and move it to the beginning of the table? It is inconsistent behaviour in my opinion.
    This is just me thinking, but maybe it is something about logical and visual indexes?




  • Lifetime Qt Champion

    @Klaudia-Pawelek said in QTableView/QAbstractItemModel: Spanned rows are not displayed correctly when a column from outside of the visible area is moved to the beginning.:

    so why does spanning works correctly when columns 2-7 are move

    by accident. As soon as the columns are moved around it's not really possible to remain the cell span. Or how should a span look like which is for col1 + col2 + col3 and then col2 is moved behind col5?

    But feel free to provide a patch to Qt :)



  • @Christian-Ehrlicher, do you think that overriding the paintEvent method (or any other method from QTableView) would be a valid workaround for this issue? The sample code provided gives consistent results in terms of how the span looks. Moving columns 2-7 always works due to the manual handling implemented in on_pushButton_clicked and by having a custom MyModel class. Moving columns 8-25 produces inconsistent span which can be by accident as you said. Maybe it is possible to prevent the problem from happening by overriding one of the QTableView methods?


  • Lifetime Qt Champion

    I don't think so. Simply take a look in the paintEvent() function of QTableView. Don't move columns what you want to use spans.


Log in to reply