Reputation: 19329
The code below creates a single QTableView
. An instance of QAbstractTableModel
is then created and assigned to it as its model. Lastly, the QItemDelegate
is assigned to the QTableView
.
The column 0 is being populated with QLineEdit
. While column 1 is populated with QComboBox
.
But even while QLineEdit
is assigned a custom text value the QLineEdit
remains to be blank. It doesn't happen with QComboBox
which properly gets three items: 'Somewhere', 'Over', 'The Rainbow'.
What should be done to pre-populate column 0 QLineEdits with the text?
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])
class Delegate(QtGui.QItemDelegate):
def __init__(self):
QtGui.QItemDelegate.__init__(self)
def createEditor(self, parent, option, index):
if index.column()==0:
lineedit=QtGui.QLineEdit(parent)
lineedit.setText('Somewhere over the rainbow')
return lineedit
elif index.column()==1:
combo=QtGui.QComboBox(parent)
combo.addItems(['Somewhere','Over','The Rainbow'])
combo.setCurrentIndex(index.row())
return combo
class Model(QtCore.QAbstractTableModel):
def __init__(self):
QtCore.QAbstractTableModel.__init__(self)
self.items = [[1, 'one', None], [2, 'two', None], [3, 'three', None]]
def rowCount(self, parent=QtCore.QModelIndex()):
return 3
def columnCount(self, parent=QtCore.QModelIndex()):
return 3
def data(self, index, role):
if not index.isValid(): return
row = index.row()
column = index.column()
if role == QtCore.Qt.DisplayRole:
return self.items[row][column]
tableModel=Model()
tableView=QtGui.QTableView()
tableView.setModel(tableModel)
tableView.setItemDelegate(Delegate())
for row in range(tableModel.rowCount()):
for column in range(tableModel.columnCount()):
index=tableModel.index(row, column)
tableView.openPersistentEditor(index)
tableView.show()
app.exec_()
Big thanks Fabio for the trick.
Working code is posted below.
Instead of handling the value assignment inside of Delegate.createEditor()
method we should implement Delegate.setEditorData(editor, index)
instead.
Inside of setEditorData
we can get both: index.column()
and index.row()
as well as to access self.items
variable used by model using index
argument value = index.model().items[row][column]
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])
class Delegate(QtGui.QItemDelegate):
def __init__(self):
QtGui.QItemDelegate.__init__(self)
def createEditor(self, parent, option, index):
if index.column()==0:
lineedit=QtGui.QLineEdit(parent)
return lineedit
elif index.column()==1:
combo=QtGui.QComboBox(parent)
return combo
def setEditorData(self, editor, index):
row = index.row()
column = index.column()
value = index.model().items[row][column]
if isinstance(editor, QtGui.QComboBox):
editor.addItems(['Somewhere','Over','The Rainbow'])
editor.setCurrentIndex(index.row())
if isinstance(editor, QtGui.QLineEdit):
editor.setText('Somewhere over the rainbow')
class Model(QtCore.QAbstractTableModel):
def __init__(self):
QtCore.QAbstractTableModel.__init__(self)
self.items = [[1, 'one', 'ONE'], [2, 'two', 'TWO'], [3, 'three', 'THREE']]
def flags(self, index):
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
def rowCount(self, parent=QtCore.QModelIndex()):
return 3
def columnCount(self, parent=QtCore.QModelIndex()):
return 3
def data(self, index, role):
if not index.isValid(): return
row = index.row()
column = index.column()
if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
return self.items[row][column]
tableModel=Model()
tableView=QtGui.QTableView()
tableView.setModel(tableModel)
tableView.setItemDelegate(Delegate())
for row in range(tableModel.rowCount()):
for column in range(tableModel.columnCount()):
index=tableModel.index(row, column)
tableView.openPersistentEditor(index)
tableView.show()
app.exec_()
Upvotes: 2
Views: 3201
Reputation: 2602
The item delegate set the editor data by setEditorData
method, that takes the model data and set it to the editor. In this case, the item delegate takes the model data (that maybe is empty) and set it to the QLineEdit
, so it set an empty string.
If you want to initialize the data in the editor, you have to reimplement setEditorData
, or initialize the data in your model.
For QComboBox
, the items are displayed correcly because setEditorData
doesn't change the items of the combo box. In general you have to reimplement setEditorData
to set the current index of the combo box depending on the model data.
I suggest to read the documentation: Model/View Programming and Delegate Classes
Upvotes: 3