Question

I'm using a custom delegate to display a column of comboBoxes in my QTableView.

In addition to the default selection issue (enter link description here) I have a problem when I reorder the data of my QTableView (per column, or by applying filters). The comboxes stay where they were when the grid was not displayed.

Is there a way I can force a repaint of the delegate ? I to copy the code of the paint method (without the index) but this only caused my program to crash.

Let me know if I'm not clear enough.

Here is the code of my custom delegate :

 class ComboBoxDelegate(QtGui.QItemDelegate):

    def __init__(self, parent, itemslist):
        QtGui.QItemDelegate.__init__(self, parent)
        self.itemslist = itemslist
        self.parent = parent

    def paint(self, painter, option, index):        
        # Get Item Data
        value = index.data(QtCore.Qt.DisplayRole).toInt()[0]
        # value = self.itemslist[index.data(QtCore.Qt.DisplayRole).toInt()[0]]
        # fill style options with item data
        style = QtGui.QApplication.style()
        opt = QtGui.QStyleOptionComboBox()
        opt.currentText = str(self.itemslist[value])
        opt.rect = option.rect


        # draw item data as ComboBox
        style.drawComplexControl(QtGui.QStyle.CC_ComboBox, opt, painter)
        self.parent.openPersistentEditor(index)

    def createEditor(self, parent, option, index):

        ##get the "check" value of the row
        # for row in range(self.parent.model.rowCount(self.parent)):
            # print row

        self.editor = QtGui.QComboBox(parent)
        self.editor.addItems(self.itemslist)
        self.editor.setCurrentIndex(0)
        self.editor.installEventFilter(self)    
        self.connect(self.editor, QtCore.SIGNAL("currentIndexChanged(int)"), self.editorChanged)

        return self.editor

    # def setEditorData(self, editor, index):
        # value = index.data(QtCore.Qt.DisplayRole).toInt()[0]
        # editor.setCurrentIndex(value)

    def setEditorData(self, editor, index):
        text = self.itemslist[index.data(QtCore.Qt.DisplayRole).toInt()[0]]
        pos = self.editor.findText(text)
        if pos == -1:  
            pos = 0
        self.editor.setCurrentIndex(pos)


    def setModelData(self,editor,model,index):
        value = self.editor.currentIndex()
        model.setData(index, QtCore.QVariant(value))


    def updateEditorGeometry(self, editor, option, index):
        self.editor.setGeometry(option.rect)

    def editorChanged(self, index):
        check = self.editor.itemText(index)
        id_seq = self.parent.selectedIndexes[0][0]
        update.updateCheckSeq(self.parent.db, id_seq, check)


    def updateDelegate(self, indexRow, indewCol):
        # index = self.parent.model.createIndex(indexRow, indewCol)

        seq_id = self.parent.model.arraydata[indexRow][0]
        print seq_id
        check = select.getCheck(self.parent.db, seq_id)
        check = check[0][0]
        print check
        if check != '':
            pos = self.checkDict[check]
        else:
            pos = 0
        self.editor.setCurrentIndex(pos)

And I call it from my QTableView class :

 self.setEditTriggers(QtGui.QAbstractItemView.CurrentChanged)
    self.viewport().installEventFilter(self)
    self.delegate = ComboBoxDelegate(self, self.checkValues)
    self.setItemDelegateForColumn(13,self.delegate)

I call the updateDelegate function when I sort the column (from the model class) :

  def sort(self, Ncol, order):
        self.emit(QtCore.SIGNAL("layoutAboutToBeChanged()"))
        self.arraydata = sorted(self.arraydata, key=operator.itemgetter(Ncol))
        i = 0
        for row in self.arraydata:
            self.parent.delegate.updateDelegate(i, 13)
            i += 1
        if order == QtCore.Qt.DescendingOrder:
            self.arraydata.reverse()
        self.emit(QtCore.SIGNAL("layoutChanged()"))

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top