QTableView : cell previous value keep showing when editing
-
Hello,
Platform: Linux Mint 5.4.0-89-generic #100-Ubuntu SMP
QtCreator: 4.15.1
Qt Version : 5.12.8 AND Qt 5.15.2I'm working with Model/View classes, trying to display a 5 column table with different type of data: Strings, Floats and Booleans.
I've selected the following classes :
A standard QTableView.
A custom QAbstractTableModel.
A custom QStyledItemDelegate for the float column to use a QSpinBox as value editor.The delegate is exactly the same as the one in the spinboxdeleate qt example.
For the custom QAbstractTableModel, I've overwritten the following functions:
int rowCount(const QModelIndex &p_parent = QModelIndex()) const override; int columnCount(const QModelIndex &p_parent = QModelIndex()) const override; QVariant data(const QModelIndex &p_index, int p_role = Qt::DisplayRole) const override; QVariant headerData(int p_section, Qt::Orientation orientation, int p_role) const override; bool setData(const QModelIndex &p_index, const QVariant &p_value, int p_role = Qt::EditRole) override; Qt::ItemFlags flags(const QModelIndex &p_index) const override; bool insertRows(int p_position, int p_rows, const QModelIndex &p_index = QModelIndex()) override;
Data is stored in a private
QList<Sample> m_data
structure .Sample
is just a struct with 2 QStrings, 1 float and 2 booleans.
Relevant code for the overwritten functions is:QVariant CTrayEditorModel::data(const QModelIndex &p_index, int p_role) const { if (checkIndex(p_index)) { // use both Display and EditRole to show data when editing if (p_role == Qt::DisplayRole || p_role == Qt::EditRole) { switch (p_index.column()) { case 0: return sample.m_well; case 1: return sample.m_name; case 2: return sample.m_concentration; default: break; } } // use this role to display checkboxes in two last columns else if (p_role == Qt::CheckStateRole) { if (p_index.column() == 3) return sample.m_isBuffer ? Qt::Checked : Qt::Unchecked; if (p_index.column() == 4) return sample.m_isViscous ? Qt::Checked : Qt::Unchecked; } else if (p_role == Qt::TextAlignmentRole) { return Qt::AlignCenter; } } return QVariant(); } bool CTrayEditorModel::setData(const QModelIndex &p_index, const QVariant &p_value, int p_role) { if (p_index.isValid()) { if (!checkIndex(p_index)) return false; const int row = p_index.row(); // on insertRows an empty element has been added to auto sample = m_data.value(row); if (p_role == Qt::EditRole) { switch (p_index.column()) { case 0: sample.m_well = p_value.toString(); break; case 1: sample.m_name = p_value.toString(); break; case 2: sample.m_concentration = p_value.toFloat(); break; default: return false; } } if (p_role == Qt::CheckStateRole) { switch (p_index.column()) { case 3: sample.m_isBuffer = p_value.toBool(); break; case 4: sample.m_isViscous = p_value.toBool(); break; default: return false; } } m_data.replace(row, sample); return true; } return false; } Qt::ItemFlags CTrayEditorModel::flags(const QModelIndex &p_index) const { // first column not editable if (p_index.column() == 0) { return (QAbstractTableModel::flags(p_index) & ~Qt::ItemIsEditable); } // 4th and 5th columns checkboxes else if (p_index.column() == 3 || p_index.column() == 4) { return (QAbstractTableModel::flags(p_index) | Qt::ItemIsUserCheckable); } // 2nd column editable string else if (p_index.column() == 1) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; } // 3rd column spinbox else { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | QAbstractTableModel::flags(p_index); } }
Code setting up the table:
m_modelView = new QTableView(); m_modelView->setSelectionBehavior(QAbstractItemView::SelectRows); m_modelView->horizontalHeader()->setStretchLastSection(true); m_modelView->verticalHeader()->hide(); m_trayModel = new CTrayEditorModel(this); m_modelView->setModel(m_trayModel); //delegate CTrayEditorDelegate* delegate = new CTrayEditorDelegate(); m_modelView->setItemDelegateForColumn(2, delegate);
The issue:
Using Qt 5.12.8 when editing cells, both the ones with string contents and the one with the spinboxdelegate, when changing the content of the cell, the previous value keeps showing, like if the default 'show delegate' was not 'covered' by the edit delegate.
See screenshot for better understanding.But compiling same code with Qt 5.15.2 , it works as expected.
I've been looking for known bugs of Qt 5.12.8 and I found nothing related to this. As I'm stuck with that Qt version for my project, I'm looking for a solution for this...
If more code needs to be given, don't hesitate to ask: I was trying not to make the post very long.
Thanks!
-
@natxo14 said in QTableView : cell previous value keep showing when editing:
Is it worth opening it??
As I said I fixed it somewhen in between. So upgrade to latest 5.12.x will most likely fix it.
-
Please take a look at the documentation to setData():
"The dataChanged() signal should be emitted if the data was successfully set."
-
Hi Christian,
Thanks for your quick answer.
I did change my code on setData() function to:if (p_index.isValid()) { ///...if (p_role == Qt::EditRole){} ... if (p_role == Qt::CheckStateRole){} m_data.replace(row, sample); qDebug() << "setData p_index : " << p_index.row() << "," << p_index.column() << ":" << p_role; QVector<int> roles = {p_role}; emit dataChanged(p_index, p_index, roles); return true; }
I have also added some debug code : it's only called (it prints what I've asked) only when the edition of the cell ends. But the bug/display issue happens while the edition happens.
As per the doc
When displaying data from models in Qt item views, e.g., a QTableView, the individual items are drawn by a delegate. Also, when an item is edited, it provides an editor widget, which is placed on top of the item view while editing takes place. QStyledItemDelegate is the default delegate for all Qt item views, and is installed upon them when they are created.
So I don't know if this is a bug (the 'display' default delegate does not 'hide' behind the 'edit' delegate for Qt 5.12 but it works for Qt 5.15) or if I'm still missing something in my code...
-
What exact version of 5.12 do you use? I know there was such a bug somewhere in 5.12 but can't find the bug report for now.
-
Thanks for your answer, Christian.
From CMakeList.txt file:
message(STATUS "Qt5 COMPONENTS VERSIONS") message(STATUS "Core: ${Qt5Core_VERSION_STRING}") message(STATUS "Widgets: ${Qt5Widgets_VERSION_STRING}")
Output:
-- Qt5 COMPONENTS VERSIONS
-- Core: 5.12.8
-- Widgets: 5.12.8 -
Can you try another style (e.g. windows) to see if it is fixed then. I really can't find the bug report anymore :)
-
Hi,
I've executed the app with-style windows
on the command line and it works as expected: the previous texts disappears and the edition of the cell content goes as expected.
Thanks for the clue, I'll think about it next time before wasting a couple of workdays :)Should this be considered as a bug?? Is it worth opening it??
Thanks! -
@natxo14 said in QTableView : cell previous value keep showing when editing:
Is it worth opening it??
As I said I fixed it somewhen in between. So upgrade to latest 5.12.x will most likely fix it.