Reputation: 71
I'm quite new to python as well as to Qt. I would like to use the QTableView
without checkboxes appearing in the tableview's cells, but as it seems they just appear there by default. As I've found out so far, you just have to deactivate the Qt.ItemIsUserCheckable
flag. But how am I supposed to do this? I tried to use the flags - function of the QAbstractItemModell inside a QAbstractTableModel
derived model class this way:
def flags(self,index):
return(QtCore.Qt.ItemIsEnabled| QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsSelectable)
So, what I did is: just not returning the Qt.ItemIsUserCheckable
flag. This works fine e.g. for the Qt.ItemIsEditable
flag making a cell editable or not (when it is not returned) but doing this with the ItemIsUserCheckable
flag has no effect on the checkboxes. So my question is: how can I get rid of the checkboxes using python? Please help!
Upvotes: 3
Views: 2139
Reputation: 1384
This catch occurs with PyQt5 as well: a QAbstractTableModel's data method must return None unless it's addressing a specific role.
So when you instantiate a model table view, each and every possible role that you might employ to give each cell attributes (such as a checkbox, a font, alignment and so on) calls the view's data method. It uses that call to determine whether it is required to help create the cell. If upon querying the method, it is told None, it does nothing.
This shouldn't be a problem, since Python methods return None if you let them run off the end.
So, with a model view designed to simply show data in each cell addressed by (row, column), it is sufficient to simply cater to that specific display role when writing the data method.
def data( self, index, role ):
if role == Qt.DisplayRole:
return self.mymodeldata[ index.row() ][ index.column() ]
The many other possible roles each also call the data method and get None in return. Thankfully, you don't have to address None to each of them specifically.
Beware though, that you do return None to all roles but those you do address in the data method, and do not instead return, say, False, as you would with some neat and clumsy logic like:
def data( self, index, role ):
return role == Qt.DisplayRole and self.mymodelData[ index.row() ][ index.column() ]
In that case, every other role gets told False. When CheckStateRole comes knocking, and gets told False, it duly shows empty checkboxes.
This would address all cases without such error:
def data( self, index, role ):
return role == Qt.DisplayRole and self.mymodelData[ index.row() ][ index.column() ] or None
Upvotes: 0
Reputation: 71
Well, I think I could sort this out on my own. The secret of the QTableView's checkboxes doesn't lie in the flag method but goes with the return value of the data-method instead. The description of the data method of QAbstractItemModel
explains that you should return an invalid QVariant
for those cases you donn't want to handle. In PyQt4.11 this means that you have to return python's None
value, because None is interpretated as invalid QVariant. So all I had to do was to make sure that the data method returns None
when I don't want to handle a role:
# works for python 3.4 and PyQt4.11
def data(self,index,role):
if not index.isValid():
return(None)
# for all roles you're not interested in, do nothing: i.e. return python's None which is interpreted as an invalid QVariant value
elif role != QtCore.Qt.DisplayRole:
return(None)
else:
return(self.data[index.row()][index.column()])
Notice, that the code returns None
for Qt.CheckStateRole
as this role is one of no interest to the code and that no checkboxes are displayed in the GUI.
Now, if you change the data method like this:
def data(self,index,role):
if not index.isValid():
return(None)
elif role == QtCore.Qt.CheckStateRole:
return("")
elif role != QtCore.Qt.DisplayRole:
return(None)
else:
return(self.data[index.row()][index.column()])
a string (""
) is returned for the Qt.CheckStateRole
which of course is not an invalid QVariant
. And -surprise, surprise - checkboxes are displayed inside the TableView.
Another point is that all this works without to implement the flags method I mentioned above.
Upvotes: 4