Moving row in QStandardItemModel unhides hidden QTreeView columns?
-
Hi,
I have aQTreeView
with a simple model class derived fromQStandardItemModel
which allows me to move rows up and down in the view. The derived class provides a single extra method calledmove(...)
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?
-
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 singleQTreeView
item, namedtreeView
, and two buttons namedupButton
anddownButton
.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.
-
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
-
From time to time, subtle regression can happen.
You might want to check the bug report system to see if there's something related.