Creating custom QLineEdit for QItemDelegate has weird inheritance
-
I am creating an app to view and edit a SQL database of floating point values using
QSqlRelationalTableModel
and aQTableView
. I want the user to be able to enter standard decimal format and scientific notation (e.g. 0.015 and 7.32515E-7).When I edit the data in the table it a default editor
QDoubleSpinBox
is used, which poorly deals with mixed precision values. I am creating a custom editor inheriting fromQLineEdit
as follows,class QFloatLineEdit(QLineEdit): def floatText(self) return float(super().text()) class CustomDelegate(QSqlRelationalDelegate): def createEditor(self, parent: QtWidgets.QWidget, option: QtWidgets.QStyleOptionViewItem, index: QtCore.QModelIndex) -> QtWidgets.QWidget: """type(editor) ==> QFloatLineEdit""" if isinstance(index.data(),float): editor = QFloatLineEdit(parent) validator = QRegularExpressionValidator(editor) re = QRegularExpression() re.setPattern(r'(([+-]?\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?)') validator.setRegularExpression(re) editor.setValidator(validator) return editor return super().createEditor(parent, option, index) def setModelData(self, editor: QtWidgets.QWidget, model: QtCore.QAbstractItemModel, index: QtCore.QModelIndex) -> None: """type(editor) ==> QLineEdit""" if isinstance(editor,QFloatLineEdit): model.setData(index,editor.floatText(),Qt.ItemDataRole.EditRole) else: super().setModelData(editor, model, index)
The
QFloatLineEdit
works in the GUI with proper regex validation. But whensetModelData
is called theeditor
has changed back toQLineEdit
class and does not get parsed with theisinstance
.Is there something I don't understand about class inheritance here or is there something happening under the hood of QT that I am not aware of?
(I am using PyQt6)
-
@VanMan
Agreed your code looks reasonable, don't know. Start by doing asetObjectName()
on theQFloatLineEdit
you create, what is the name insetModelData()
? Are the Pythonid
s of the twoeditor
s indeed different? Also verify theindex
es are indeed the same! -
@VanMan Then I'd look at your
isinstance()
call which you assume should work. If they have the same ids then they sound like the same object to me.I see what you mean though from the different type outputs.... You don't happen to have PySide6 to try it? For now, never mind the claimed instance type, what happens if you let it call
editor.floatText()
anyway? Does it call yours inQFloatLineEdit
or does it barf? -
When I try to run
editor.floatText
it errorsAttributeError: 'QLineEdit' object has no attribute 'floatText'
. So it seems somehow the QLineEdit is getting overridden, but retains the QValidator somehow...Using
setObjectName
I can set the name and retrieve the name insetEditorData
, so I can make a workaround and put thefloat()
call insetEditorData
.I don't have PySide6 available for easy testing. But may install it later to test behaviour.
-