Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Creating custom QLineEdit for QItemDelegate has weird inheritance

Creating custom QLineEdit for QItemDelegate has weird inheritance

Scheduled Pinned Locked Moved Solved Qt for Python
qt for python
7 Posts 2 Posters 519 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    VanMan
    wrote on last edited by
    #1

    I am creating an app to view and edit a SQL database of floating point values using QSqlRelationalTableModel and a QTableView. 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 from QLineEdit 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 when setModelData is called the editor has changed back to QLineEdit class and does not get parsed with the isinstance.

    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)

    JonBJ 1 Reply Last reply
    0
    • V VanMan

      I am creating an app to view and edit a SQL database of floating point values using QSqlRelationalTableModel and a QTableView. 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 from QLineEdit 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 when setModelData is called the editor has changed back to QLineEdit class and does not get parsed with the isinstance.

      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)

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @VanMan
      Agreed your code looks reasonable, don't know. Start by doing a setObjectName() on the QFloatLineEdit you create, what is the name in setModelData()? Are the Python ids of the two editors indeed different? Also verify the indexes are indeed the same!

      1 Reply Last reply
      0
      • V Offline
        V Offline
        VanMan
        wrote on last edited by VanMan
        #3

        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>

        JonBJ 1 Reply Last reply
        0
        • V VanMan

          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>

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @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 in QFloatLineEdit or does it barf?

          1 Reply Last reply
          0
          • V Offline
            V Offline
            VanMan
            wrote on last edited by
            #5

            When I try to run editor.floatText it errors AttributeError: '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 in setEditorData, so I can make a workaround and put the float() call in setEditorData.

            I don't have PySide6 available for easy testing. But may install it later to test behaviour.

            JonBJ 1 Reply Last reply
            0
            • V VanMan

              When I try to run editor.floatText it errors AttributeError: '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 in setEditorData, so I can make a workaround and put the float() call in setEditorData.

              I don't have PySide6 available for easy testing. But may install it later to test behaviour.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @VanMan
              Yes that sounds odd! Since you are using PyQt you could join https://riverbankcomputing.com/mailman/listinfo/pyqt and post your question. If someone replies they know their stuff there.

              1 Reply Last reply
              0
              • V Offline
                V Offline
                VanMan
                wrote on last edited by
                #7

                I'll use the workaround for now, and post there to see if they can identify anything related to PyQt. Thanks for the help.

                1 Reply Last reply
                0
                • V VanMan has marked this topic as solved on

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved