Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QComboBox selection doesn't update or draw when not clicked in QTableView



  • Hello everyone! This is my first post, I apologize if I am phrasing anything awkwardly.
    I am attempting to populate a QTableView with a QComboBox in PyQt. This is the delegate class:

    class ComboTask(QtGui.QStyledItemDelegate):
        def __init__(self, parent=None):
            super(ComboTask, self).__init__(parent)
            # task dictionary
            self.taskDict = []
            self.emptyTask = "未入力"
        def createEditor (self, parent, option, index):
            combo = QtGui.QComboBox(parent)
            linkText = index.model().data(index.sibling(index.row(), 2), QtCore.Qt.DisplayRole).toString()
            #I add an emptyTask which is selected by default, then populate the rest of the combo box
            tasks = self.taskDict
            combo.addItem(self.emptyTask)
            for task in tasks:
                combo.addItem(task)
            return combo
            
        def setEditorData (self, editor, index):
            value = index.model().data(index, QtCore.Qt.EditRole)
            editor.setCurrentIndex(editor.findData(value))
            
        def setModelData (self, editor, model, index):
            value = editor.itemData(editor.currentIndex())
            model.setData(index, value, QtCore.Qt.EditRole)
            
        def paint (self, painter, option, index):
            myOption = option
            taskID = index.model().data(index, QtCore.Qt.DisplayRole).toInt()[0]
            linkText = index.model().data(index.sibling(index.row(), 2), QtCore.Qt.DisplayRole).toString()
            tasks = self.taskDict
            #taskID is always 0.
            if taskID == 0:
                myOption.text = self.emptyTask
            
            else:
                for task in tasks:
                    #I was hoping that if I could get taskID to reflect the index of the selected item in the combo box, I could set the option text here.
                    if (task.index()+1) == taskID:
                        myOption.text = task
                        break
            painter.save()
            QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_ItemViewItem, myOption, painter)
            painter.restore()
    

    Any idea why it isn't updating? Additionally, the QComboBox only shows when clicked in its cell, and shows a blank field until I drop down the options.



  • editor.findData and editor.itemData act on the user data of the item not on the string that's actually shown. use editor.findText and editor.itemText instead


  • Lifetime Qt Champion

    Hi,

    To add to @VRonin, your self.taskDict variable is not a dict but an array which is pretty different.

    Also, why are you re-implementing the paint method ? By default, you should see the content you selected from the combobox.



  • @VRonin That brings me very close! Now the QComboBox retains the selection when I click another element then come back to the cell in the QTableView containing it. However, clicking another element shows the text of the emptyTask from line 6. Do you have any idea how I might update that text with the newly-selected entry in QComboBox?

    Thank you for your help and speedy reply!



  • @SGaist My apologies. It's called taskDict because of an earlier implementation which used a dictionary. I should have refactored before posting.

    And yes! That did it! I was overthinking it and tried reimplementing paint() when it was unnecessary. Thank you so much!


Log in to reply