How to make QAbstractTableModel 's data checkable

  • I want to make each cell in the following code can be checked or unchecked by the user ,how to modify the code ?

    @import sys

    from PyQt4.QtGui import *

    from PyQt4.QtCore import *

    class MyModel(QAbstractTableModel):

    def __init__(self, parent=None):   
        super(MyModel, self).__init__(parent)   
    def rowCount(self, parent = QModelIndex()):   
        return 2
    def columnCount(self,parent = QModelIndex()) :   
        return 3
    def data(self,index, role = Qt.DisplayRole) :   
        if (role == Qt.DisplayRole):   
            return "Row{}, Column{}".format(index.row() + 1, index.column() +1)   
        return None

    if name == 'main':

    app =QApplication(sys.argv)   
    myModel = MyModel (None);   
    tableView.setModel( myModel );   

  • To be checkable, a model must return the necessary flag from the flags() method, provide legal data from the data() method with the CheckStateRole and also implement the setData() method to allow for the check state to change. See the following full example:

    import sip

    from PyQt4.QtGui import *
    from PyQt4.QtCore import *

    class MyModel(QAbstractTableModel):
    def init(self, parent=None):
    QAbstractTableModel.init(self, parent)

        self._checked=[[False for i in xrange(self.columnCount())] for j in xrange(self.rowCount())]
    def rowCount(self, parent = QModelIndex()): return 2
    def columnCount(self,parent = QModelIndex()): return 3
    def data(self,index, role = Qt.DisplayRole):
        if not index.isValid(): return
        if (role == Qt.DisplayRole):
            return "Row{}, Column{}".format(index.row()+1, index.column()+1)
        elif role==Qt.CheckStateRole: return self._checked[index.row()][index.column()]
        return None
    def flags(self, index):
        if not index.isValid(): return
        return Qt.ItemIsSelectable|Qt.ItemIsEditable|Qt.ItemIsEnabled|Qt.ItemIsUserCheckable
    def setData(self, index, value, role):
        if not index.isValid() or role!=Qt.CheckStateRole: return False
        self.dataChanged.emit(index, index)
        return True

    if name == 'main':
    from sys import argv, exit

    class Widget(QWidget):
        def __init__(self, parent=None, **kwargs):
            QWidget.__init__(self, parent, **kwargs)


    Hope this helps ;o)

  • is it necessary to check if the index is valid ?
    I post a thread about this question here ,can you have a look ?

  • I am in the habit of always checking the validity of the index when working with models of any shape (list, table, tree) or dimension. With tree models it's more important, but even with lists and tables, for what it realistically costs (which is very little), a bit of defensive programming to prevent unseemly UI errors, crashes or even segmentation faults (this can happen!) is worth it. I regularly work with models that are 100's and 1000's of columns wide and 1,000,000's of rows long and it doesn't have an adverse effect.

    WRT to this:

    if (!index.isValid())
    return QVariant();

     if (index.row() >= stringList.size())
         return QVariant();


    The second check is entirely contextual: if/how you do this is based on the likelihood of bad/non-existant accesses and the underlying data structures ability to handle these.

    So I suppose the long and the short of it is: check the validity of the index as there's no reason not to, check the validity of the data access as/if/when appropriate to your design.

    Hope this answers your question ;o)

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.