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
Forum Updated to NodeBB v4.3 + New Features

Creating custom QLineEdit for QItemDelegate has weird inheritance

Scheduled Pinned Locked Moved Solved Qt for Python
qt for python
7 Posts 2 Posters 549 Views 1 Watching
  • 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 17 Jul 2024, 17:39 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)

    J 1 Reply Last reply 17 Jul 2024, 17:49
    0
    • V VanMan
      17 Jul 2024, 17:39

      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)

      J Offline
      J Offline
      JonB
      wrote on 17 Jul 2024, 17:49 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 17 Jul 2024, 17:54 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>

        J 1 Reply Last reply 17 Jul 2024, 17:58
        0
        • V VanMan
          17 Jul 2024, 17:54

          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>

          J Offline
          J Offline
          JonB
          wrote on 17 Jul 2024, 17:58 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 17 Jul 2024, 18:25 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.

            J 1 Reply Last reply 17 Jul 2024, 18:32
            0
            • V VanMan
              17 Jul 2024, 18:25

              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.

              J Offline
              J Offline
              JonB
              wrote on 17 Jul 2024, 18:32 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 17 Jul 2024, 18:36 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 17 Jul 2024, 18:37

                5/7

                17 Jul 2024, 18:25

                • Login

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