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

ComboBox Delegate edit the wrong row in QTableView



  • Hello,

    I want to be able to edit values in a specific column in my TableView, through a combobox. I've create a QItemDelegate subclass.

    here's my code:

    class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    
    	def __init__(self, mlist=None):
    		super(MainWindow, self).__init__()
    		self.Table = QtWidgets.QTableView
    		self.model = TableModel() #QAbstractTableModel subclass
    		self.proxyModel = ProxyModel() #QSortFilterProxyModel subclass
    
    		self.proxyModel.setsourceModel(self.model)
    		self.Table.setModel(self.proxyModel)
    		self.Table.setItemDelegateForColumn(10, ComboBoxItemDelegate())
    
    class ComboBoxItemDelegate(QtWidgets.QItemDelegate):
    	
    	def __init__(self, parent=None):
    		QtWidgets.QItemDelegate.__init__(self,parent)
    		self._items = [str(type) for type in TYPES_POINTS.values()] 
    
    	def createEditor(self, widget, option, index):
    		editor = QtWidgets.QComboBox(widget)
    		editor.addItems(self._items)
    		return editor
    
    	def setEditorData(self, editor, index):
    		value = int(index.model().sourceModel().data(index, QtCore.Qt.EditRole))
    		if value:
    			editor.setCurrentIndex(value)
    
    	def setModelData(self, editor, model, index):
    		model.sourceModel().setData(index, editor.currentIndex(), QtCore.Qt.EditRole)
    
    	def updateEditorGeometry(self, editor, option, index):
    		editor.setGeometry(option.rect)
    

    What happens is when I double click a cell in the 10th column, I displays the values I want, I choose I value, hit enter, the value changes but in a different row. The problem is caused (in my opinion) by the proxyModel, the rows are displayed in different order because of the ProxyModel sort method (Lessthan() ).

    Any way to solve that ?

    thanks,



  • @hachbani
    When you use a proxy model you must be prepared to map between proxy indexes and source model indexes, because the whole point is they may not have the same row/column numbers. See https://doc.qt.io/qt-5/qabstractproxymodel.html#mapFromSource & https://doc.qt.io/qt-5/qabstractproxymodel.html#mapSelectionToSource.



  • I've read about reimplementing mapfromSource & mapToSource methods, but can't figure out how to reiplement them. I'm struggling to find examples to guide me. Any idea about where to start ?
    thanks



  • @hachbani
    You do not need to do any re-implementing here. The QSortFilterProxyModel you are using has already done that in its implementation of the map functions. You just need to call them, wherever you need to convert between indexes into the proxy model versus indexes into the source model.



  • @JonB I've solved the issue by replacing model.sourceModel() by model . It works even though it's not a clean way to do it.

    Do you know how can I open the editor just by a single click event ? because now I have to first double click the cell, then an additional click to show the comboBox list


  • Lifetime Qt Champion

    Hi,

    Why is it not clean ?

    You could have several proxies on top of each other.

    You should always access the top most model.

    You can change the edit trigger and select single click.



  • @SGaist said in ComboBox Delegate edit the wrong row in QTableView:

    You can change the edit trigger and select single click.

    I actually looked at https://doc.qt.io/qt-5/qabstractitemview.html#EditTrigger-enum and not sure you can do that? I don't think QAbstractItemView::SelectedClicked is what the OP is asking for. @hachbani There is a whole stackoverflow topic for this, Qt: start editing of cell after one click for a combobox, you might want to read the possibilities there.


  • Lifetime Qt Champion

    I had CurrentChanged in mind.



  • @SGaist
    I would never argue with you :) Yes, I didn't even notice that one. We'll see what the OP makes of it, there must be a reason for all those solutions!


  • Lifetime Qt Champion

    @JonB said in ComboBox Delegate edit the wrong row in QTableView:

    I would never argue with you :)

    No please do, I do make mistakes :-)



  • @SGaist
    @hachbani has complained that

    then an additional click to show the comboBox list

    For CurrentChanged, and other edit triggers, don't they just put the combobox in the cell but not expand it? I think the stackoverflow proposals are to do with getting the combo's dropdown list to pop up immediately (on the single-click-to-edit), which the OP was asking for.


  • Lifetime Qt Champion

    @JonB said in ComboBox Delegate edit the wrong row in QTableView:

    @SGaist
    @hachbani has complained that

    then an additional click to show the comboBox list

    For CurrentChanged, and other edit triggers, don't they just put the combobox in the cell but not expand it? I think the stackoverflow proposals are to do with getting the combo's dropdown list to pop up immediately (on the single-click-to-edit), which the OP was asking for.

    See ? You were right to argue, I missed the "triple click" issue :-)


Log in to reply