Moving row in QStandardItemModel unhides hidden QTreeView columns?



  • Hi,
    I have a QTreeView with a simple model class derived from QStandardItemModel which allows me to move rows up and down in the view. The derived class provides a single extra method called move(...) which does the work. It is implemented as in this post.

    My model has only two columns, one of which is hidden (the last). The row moving mechanism works fine. However, since I migrated to Qt 5.9.4, moving a row in this way unhides the hidden column!? This did not happen in Qt 5.9.2 (I'm working on Windows 10, compiling with Visual Studio 2017 community).

    Why does this unhiding happen and how can I keep the hidden column hidden?


  • Lifetime Qt Champion

    Hi,

    Can you show a minimal compilable version that can reused to test that behaviour ?



  • @SGaist
    I tried uploading a minimal example in a zip archive, but I have not enough privileges to do so. I therefore add the code here.

    The mainwindow.ui form contains a single QTreeView item, named treeView, and two buttons named upButton and downButton.

    I can confirm that the the problem occurs with 5.9.4 but not in 5.9.2.

    dragstandarditemmodel.h:

    #ifndef DRAGSTANDARDITEMMODEL_H
    #define DRAGSTANDARDITEMMODEL_H
    
    //#include <QAbstractItemModel>
    #include <QStandardItemModel>
    
    
    class DragStandardItemModel : public QStandardItemModel
    {
        Q_OBJECT
    
    public:
        DragStandardItemModel(int rows, int columns, QObject *parent = Q_NULLPTR);
        bool move(int from, bool isUp);
    };
    
    #endif // DRAGSTANDARDITEMMODEL_H
    
    

    dragstandarditemmodel.cpp:

    #include "dragstandarditemmodel.h"
    
    #include <QDebug>
    
    DragStandardItemModel::DragStandardItemModel(int rows, int columns, QObject *parent)
        : QStandardItemModel(rows, columns, parent)
    {
    
    }
    
    bool DragStandardItemModel::move(int from, bool isUp)
    {
        //range checking etc.
        const int numRows = rowCount();
    
        if (from<0 || from>=numRows || (from==0 && isUp) || (from==numRows-1 && !isUp))
            return false;
    
        const int to = isUp ? from - 1: from + 1;
        const int toSignal = isUp ? to : to + 1;
    
        if (!beginMoveRows(QModelIndex(), from, from, QModelIndex(), toSignal))
            return false;
    
        blockSignals(true);
    
        QList<QStandardItem*> fromRow = takeRow(from);
        beginInsertRows(QModelIndex(), toSignal, toSignal);
        insertRow(to, fromRow);
    
        blockSignals(false);
    
        endMoveRows();
    
        return true;
    }
    

    mainwindow.h:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    class DragStandardItemModel;
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private slots:
        void on_upButton_clicked();
        void on_downButton_clicked();
    
    private:
        Ui::MainWindow *ui;
        DragStandardItemModel* m_colModel;
    
        void moveCurrentRow(bool isUp);
    };
    
    #endif // MAINWINDOW_H
    

    mainwindow.cpp:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include "dragstandarditemmodel.h"
    
    #include <QStandardItem>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        //Create model, fill some data, hide 2nd column
        const int numRows = 10;
        const int numCols = 2;
    
        m_colModel = new DragStandardItemModel(numRows, numCols, ui->treeView);
    
        for (int i=0; i<numRows; ++i)
        {
            QStandardItem* itm = new QStandardItem(QString::number(i+1));
            itm->setCheckable(true);
            itm->setCheckState(Qt::Checked);
            m_colModel->setItem(i, 0, itm);
    
            //Hidden column, to contain the logical index of visual item at i
            itm = new QStandardItem(QString::number(i));
            m_colModel->setItem(i, 1, itm);
        }
    
        m_colModel->setHorizontalHeaderLabels({"Info"});
        ui->treeView->setModel(m_colModel);
        ui->treeView->setColumnHidden(1, true);
        ui->treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
    
        ui->treeView->setRootIsDecorated(false);
        ui->treeView->resizeColumnToContents(0);
        ui->treeView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->treeView->adjustSize();
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::moveCurrentRow(bool isUp)
    {
        const QModelIndex index = ui->treeView->currentIndex();
    
        if (index.isValid())
        {
            const int row = index.row();
    
            if (m_colModel->move(row, isUp))
            {
                const QModelIndex newIndex = m_colModel->index(isUp ? row-1 : row+1, 0);
                ui->treeView->setCurrentIndex(newIndex);
            }
        }
    }
    
    void MainWindow::on_upButton_clicked()
    {
        moveCurrentRow(true);
    }
    
    void MainWindow::on_downButton_clicked()
    {
        moveCurrentRow(false);
    }
    

    For now, I just re-hide the column after each move, by adding the following line before the setCurrentIndex() operation:

    ui->treeView->setColumnHidden(1, true);
    

    But this is just an uggly temp workaround.


  • Lifetime Qt Champion

    Can you check with 5.10 ? Seems to work correctly.



  • @SGaist said in Moving row in QStandardItemModel unhides hidden QTreeView columns?:

    Can you check with 5.10 ? Seems to work correctly

    Well, of course I could do that, and from what you wrote, it seems to work there.

    But then, I don't really understand the point of releasing the patch release 5.9.4, if in addition to solving bugs, introduces new ones, such as this one...

    EDIT: Just checked: it works correctly in 5.10


  • Lifetime Qt Champion

    From time to time, subtle regression can happen.

    You might want to check the bug report system to see if there's something related.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.