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
QSqlRelationalTableModeland 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
QDoubleSpinBoxis used, which poorly deals with mixed precision values. I am creating a custom editor inheriting fromQLineEditas 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
QFloatLineEditworks in the GUI with proper regex validation. But whensetModelDatais called theeditorhas changed back toQLineEditclass 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)
-
I am creating an app to view and edit a SQL database of floating point values using
QSqlRelationalTableModeland 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
QDoubleSpinBoxis used, which poorly deals with mixed precision values. I am creating a custom editor inheriting fromQLineEditas 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
QFloatLineEditworks in the GUI with proper regex validation. But whensetModelDatais called theeditorhas changed back toQLineEditclass 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 theQFloatLineEdityou create, what is the name insetModelData()? Are the Pythonids of the twoeditors indeed different? Also verify theindexes are indeed the same! -
I'll take a look at the object names, but the Python ids were the same:
<customWidgets.QFloatLineEdit object at 0x000001BDFC192170>
<PyQt6.QtWidgets.QLineEdit object at 0x000001BDFC192170>@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 inQFloatLineEditor does it barf? -
When I try to run
editor.floatTextit errorsAttributeError: 'QLineEdit' object has no attribute 'floatText'. So it seems somehow the QLineEdit is getting overridden, but retains the QValidator somehow...Using
setObjectNameI 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.
-
When I try to run
editor.floatTextit errorsAttributeError: 'QLineEdit' object has no attribute 'floatText'. So it seems somehow the QLineEdit is getting overridden, but retains the QValidator somehow...Using
setObjectNameI 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.
-
V VanMan has marked this topic as solved on