Reputation: 16242
I'm trying to figure out how to work with the models and views in PyQt4.9.1 and I've run into a bit of a problem.
Here's the code that matters:
class TestModel(QtGui.QStandardItemModel):
def __init__(self,parent=None):
QtGui.QStandardItemModel.__init__(self,parent)
self.initData()
self.headings = ['name','value','']
def initData(self):
self.rows = [['name {0}'.format(i), i] for i in range(20)]
def data(self, index, value, role):
print ("foo")
if not index.isValid():
return
if (role == QtCore.Qt.DisplayRole):
row = index.row()
col = index.column()
if (col == 3):
return "BUTTON GOES HERE"
return self.rows[row][col]
def headerData(self,section,orientation,role):
if (role == QtCore.Qt.DisplayRole):
if (orientation == QtCore.Qt.Horizontal):
return self.headings[section]
def rowCount(self,parent):
return len(self.rows)
def columnCount(self,parent):
return 3
class MainWindow(QtGui.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.m = TestModel()
self.initUi()
def initUi(self):
layout = QtGui.QVBoxLayout()
widget = QtGui.QTableView()
widget.setModel(self.m)
layout.addWidget(widget)
self.setLayout(layout)
self.show()
Here's what happens when I launch my application's MainWindow: There are no error messages, the table is drawn with the right number of rows and columns and the correct headings, but the table is empty. You might notice that the model's draw method starts off with a print statement. That statement is never reached. Is there something I'm missing? I cant find any tutorials at all for PyQt4.9.1.
Upvotes: 1
Views: 359
Reputation: 29896
data()
doesn't have any value
parameter, but removing it doesn't solve the problem.
The virtual method index(row, column, parent)
, which is called whenever a QModelIndex
needs to be created, always returns an invalid index for QStandardItemModel
, unless a QStandardItem
was explicitly created for the requested index. The view probably doesn't try to display cells when the index is invalid, so data()
is never called.
If you kept inheriting from QStandardItemModel
, you would need to reimplement index()
to create valid indexes, but since you are using your own structure to store the data instead of using QStandardItem
, you could simply inherit from QtCore.QAbstractTableModel
:
class TestModel(QtCore.QAbstractTableModel):
def __init__(self,parent=None):
super(TestModel, self).__init__(parent)
self.initData()
self.headings = ['name','value','']
def initData(self):
self.rows = [['name {0}'.format(i), i] for i in range(20)]
def data(self, index, role):
if index.parent().isValid():
return None
if (role == QtCore.Qt.DisplayRole):
row = index.row()
col = index.column()
# 3rd column index is 2 not 3
if (col == 2):
return "BUTTON GOES HERE"
# that return should also be "inside" the role DisplayRole
return self.rows[row][col]
return None
def headerData(self,section,orientation,role):
if (role == QtCore.Qt.DisplayRole):
if (orientation == QtCore.Qt.Horizontal):
return self.headings[section]
Also, you should only return a non-zero row/column count for top-level items (the one without parent), if you are not representing a tree model :
def rowCount(self,parent):
if not parent.isValid():
return len(self.rows)
return 0
def columnCount(self,parent):
if not parent.isValid():
return 3
return 0
Upvotes: 1