Important: Please read the Qt Code of Conduct -

QStyledItemDelegate setEditorData not disaply in TableView

  • I'm using PyQt4 and have implemented a TableView using the Model/View design. I'm adding a delegate to allow editing of one of my fields, but don't seem to have control over the data displayed while editing. I've implemented my own QStyledItemDelegate and the function setEditorData. I can see it getting called, but the text I set using editor.setText() is never displayed. It seems like my Models data is getting rendered instead. I can see it called immediately after setEditorData with the DisplayRole.

    The result is that the item is highlighted immediately after selection and the delegates editor seems to only appear once I start typing in the item at which time all data is cleared and only the character I typed is displayed.

    The data I entered is set ok, but I would like to allow the user to actually edit the data in the item rather than having to replace all of it. I don't understand why, when I start typing all the data is cleared except for what I typed.

    The data value show is all zeros, I never see the "11223344..."
    The relevant code is as follows:

    class dmaDelegate(QtGui.QStyledItemDelegate):
       def __init__(self, parent):
          super(dmaDelegate, self).__init__(parent)
       def createEditor(self, parent, option, index):
          if index.column() == 1:
             editor = QtGui.QLineEdit(parent)
             regex = QtCore.QRegExp("[A-Za-z0-9]{16}")
             validator = QtGui.QRegExpValidator(regex, parent)
             return editor
       def setEditorData(self, editor, index):
          if index.column() == 1:
             value = "00112233445566778899aabbccddeeff"
       def setModelData(self, editor, model, index):
          if index.column() == 1:
             value = editor.text()
             model.setData(index, value, QtCore.Qt.EditRole)
    class dmaModel(QtCore.QAbstractTableModel):
       def __init__(self, parent):
       def data(self, index, role):
          if role == QtCore.Qt.DisplayRole:
             if index.column() == 0:
                ## display address (16 bits per row)
                return QtCore.QString("0x%08x" % address)
                ## display data
                data = self.getMemory(address, stop_address)
                return QtCore.QString(data)
          return QtCore.QVariant()
       def flags(self, index):
          my_flags = QtCore.Qt.NoItemFlags
          if index.column() == 1: # only value is editable
             return QtCore.Qt.ItemIsEnabled\
                  | QtCore.Qt.ItemIsSelectable\
                  | QtCore.Qt.ItemIsEditable
          # all other indexes and fields are not editable
          return my_flags
       def setData(self, index, varient, role):
          VERBOSE("dmaModel: setData %s", str(varient))
    class myapp(QtGui.QMainWindow):
       def __init__(self)
                  self.dma_model = dmaModel(self)
                  self.dma_delegate = dmaDelegate(self)

    Searching on the issue gave me one result talking about Qt's implementation calling selectAll() after setEditorData() and they used a complicated lambda and QueuedConnection to solve the problem:
    There must be a better way to accomplish this.

  • @brookbot
    I admit I don't understand what you're asking, and you are probably further advanced than this since you are looking at some specific SO post. But how will the code you show work given that your dmaModel.setData() doesn't store the data in the model?

Log in to reply