Intermittent problem with QItemEditorFactory in QTableView QAbstractTableModel
-
Hi,
Many of my applications make heavy use of QTableView's and QAbstractTableModel's.
Recently one of my software customers (on macOS Mojave) reported a QDoubleSpin box appearing when attempting to edit some of the table cells. The cells show decimal numbers and I've confirmed the cells ALL return QString() for both the DisplayRole and the EditRole in QAbstractTableModel's data() function. According to the QItemEditorFactory documentation, QString should always results in the editor being a QLineEdit (not a QDoubleSpinBox).
When the customer restarted the application, all cell editing was back to normal using QLineEdit, and he's not seen the problem since. So it's quite difficult to replicate.
Wondering if anyone else has experienced this and knows why it might happens?
Thanks,
Michael -
For a valid
QModelIndex index
, what doesqDebug() << index.data(Qt::EditRole).userType()
return? try printing that value both before anybody ever edited the value and after setting the value to 1.5 by editing the cell in the ui
P.S.
The cells show decimal numbers and I've confirmed the cells ALL return QString() for both the DisplayRole and the EditRole in QAbstractTableModel's data() function.
This is an atrocity. The conversion from number to string should be done in the delegate, not the model:
- The model is locale unaware
- Storing string representations of numbers breaks sorting
-
Actually I don't need sorting in these tables.
P.S.
The cells show decimal numbers and I've confirmed the cells ALL return QString() for both the DisplayRole and the EditRole in QAbstractTableModel's data() function.
This is an atrocity. The conversion from number to string should be done in the delegate, not the model:
That's a harsh comment. It's completely up to the programmer. I want consistent display of the float in the editor - e.g. 2 decimal places - and then I handle txt to float conversion again in the setData() model method. And I don't want the default double editor which includes the double spinner.
-
Sure it's up to the programmer. The programmer is free to manually paint every single widget from scratch and implement its own version of a dinamic container but, as in the other two example, this is not what you want to be doing. The model-view-delegate paradigm wants the model to only care about raw data, not how the user interacts with it. The delegate is the right place to do that instead of reimplementing
setData
. We are discussing it in another thread, if interested: https://forum.qt.io/post/562707And I don't want the default double editor which includes the double spinner.
Again, the easiest solution is just to subclass a delegate and have it return a
QLineEdit
all the time. It also ends up being more efficient than the default one as you don't have to mess around with named properties and you can directly retrievestatic_cast<QLineEdit*>(editor)->text()
-
This is an atrocity.
That's a harsh comment.
@VRonin speaks his mind! :) I have been doing something like you wrt
DisplayRole
(though only fordata()
, not forsetData()
) and the string formatting of numerics. I see that @VRonin has linked to that thread, where he replied to me on this issue, and I would advise you read through it as I have done, it's very useful. I saw it your way, but now I must accept this is not the way to do it at least with Qt's model-view, and will change over toQStyledItemDelegate
in future. -
@VRonin said in Intermittent problem with QItemEditorFactory in QTableView QAbstractTableModel:
Again, the easiest solution is just to subclass a delegate and have it return a
QLineEdit
all the time. It also ends up being more efficient than the default one as you don't have to mess around with named properties and you can directly retrievestatic_cast<QLineEdit*>(editor)->text()
I understand but personally I don't think this is easier. I have 10-15 tables in one app with different decimal place requirements for cells, based on a variety of other criteria. Instantiating multiple delegates* and reassigning them on a cell-by-cell basis is more complicated than returning a formatted string from ::data(); just the way I like it. And when the string comes back in ::setData(), in addition to string-to-double or string-to-int conversion, I have different range checking for each cell based on other cell settings.
'* Setting a delegate for a column, row or even a cell isn't workable, given the way I'm using the table and dynamically changing the behaviour of cells based on other cell settings.
Michael
-
But has anyone experienced anything like that described in the original post above?