Reputation: 4777
I'm using a QTableView
and sub-classed a QAbstractTableModel
. When editing a cell I noticed that QAbstractTableModel.setData
only goes through the last selected cell. Is there a way to get setData
to work with multiple (selected) cells?
As an example of usage:
I tried sub-classing closeEditor
, then looping through selectedIndexes
to call them with setData
, but I don't know how to get the user's input value from closeEditor
.
Here's my attempt, almost got it, just need the input value.
def closeEditor(self, editor, hint):
is_cancelled = (hint == QtGui.QAbstractItemDelegate.RevertModelCache)
if not is_cancelled:
for index in self.selectedIndexes():
if index == self.currentIndex():
continue
input_value = ??? # Don't know how to get this from here!
self.model().setData(index, input_value, QtCore.Qt.EditRole)
return QtGui.QTableWidget.closeEditor(self, editor, hint)
Upvotes: 2
Views: 1340
Reputation: 4777
Edit: I was using this as a workaround as there was a bug in PySide where editor
was only returning a QWidget
. Please look at Kevin Krammer's answer!
Though it's a slight work around, the solution I have so far seems to be working fine. Please let me know if there's a better way, this is a bit long-winded.
In closeEditor
I make every cell pass through setData
with None
as the value.
Then in QAbstractTableModel
I have a variable there _input_value
that will store the user's input for the rest of the cells to grab.
class TableView(QtGui.QTableView):
def __init__(self, parent=None):
super(TableView, self).__init__(parent)
def closeEditor(self, editor, hint):
is_cancelled = (hint == QtGui.QAbstractItemDelegate.RevertModelCache)
if not is_cancelled:
for index in self.selectedIndexes():
if index == self.currentIndex():
continue
# Supply None as the value
self.model().setData(index, None, QtCore.Qt.EditRole)
# Reset value for next input
if self.model()._input_value is not None:
self.model()._input_value = None
return QtGui.QTableWidget.closeEditor(self, editor, hint)
class TableModel(QtCore.QAbstractTableModel):
def __init__(self, parent=None):
super(TableModel, self).__init__(parent)
self.main_widget = parent
self._input_value = None
def setData(self, index, value, role):
# Triggers if user cancelled input
if value is None and self._input_value is None:
return False
if self._input_value is None:
# The last selected cell will pass through here to store the value.
self._input_value = value
else:
# All other cells will pass None, so just grab our stored value.
value = self._input_value
# Do whatever you want with value now
return True
Upvotes: 0
Reputation: 5207
The editor
in the closeEditor
signal is the widget that was used for editing.
If that is, for example a QLineEdit
you can read the text of it through its text
property.
One way to retrieve the property value is through QObject's property API
value = editor.property("text")
Upvotes: 2