1

I am using own table model with QAbstractTableModel, where I have first col with checkbox (checkable cause flags Qt.ItemIsUserCheckable | Qt.ItemIsSelectable | Qt.ItemIsEnabled). I have trouble when I am trying use checkboxes, cause they are not checkable (can not make check or uncheck in them) in showed table.

What am I doing wrong? I am using this methods in own table model class:

def data(self, index, role):

    row = index.row()
    col = index.column()

    if role == Qt.DisplayRole:
        return '{0}'.format(self.tableData[row][col])

    if role == Qt.CheckStateRole: 
        if col == 0:
            return Qt.Unchecked
        else: 
            return None

def setData(self, index, value, role):
    if not index.isValid():
       return False

    if (role == Qt.CheckStateRole):
        if (index.data(Qt.CheckStateRole) == Qt.Checked):
            return True
        else:
            return False
    else:
        return False
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Dave
  • 87
  • 9

1 Answers1

3

You have to store the states for it, we need to have something permanent as a reference, for this we use QPersistentModelIndex, in this case a dictionary where the key is the QPersistentModelIndex and the value is the state of QCheckBox.

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


class TableModel(QAbstractTableModel):
    def __init__(self, parent=None):
        super(TableModel, self).__init__(parent)
        self.tableData = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
        self.checks = {}

    def columnCount(self, *args):
        return 3

    def rowCount(self, *args):
        return 3

    def checkState(self, index):
        if index in self.checks.keys():
            return self.checks[index]
        else:
            return Qt.Unchecked

    def data(self, index, role=Qt.DisplayRole):
        row = index.row()
        col = index.column()
        if role == Qt.DisplayRole:
            return '{0}'.format(self.tableData[row][col])
        elif role == Qt.CheckStateRole and col == 0:
            return self.checkState(QPersistentModelIndex(index))
        return None

    def setData(self, index, value, role=Qt.EditRole):

        if not index.isValid():
            return False
        if role == Qt.CheckStateRole:
            self.checks[QPersistentModelIndex(index)] = value
            return True
        return False

    def flags(self, index):
        fl = QAbstractTableModel.flags(self, index)
        if index.column() == 0:
            fl |= Qt.ItemIsEditable | Qt.ItemIsUserCheckable
        return fl


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    view = QTableView()
    model = TableModel()
    view.setModel(model)
    view.show()
    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Thank you for your repply, but I have trouble still. Checkbox is not able to check by mouse or any other way. Just showed, but not usable – Dave May 01 '18 at 22:48
  • I am using PyQt4 – Dave May 01 '18 at 23:00
  • Thank you a lot! Now it seems work with changing states. But what is strange, by mouse only some checkboxes reacts with tick. By using spacebar every seems immidately ticking and works fine. Or is something for setting item behavior while using mouse with it? – Dave May 01 '18 at 23:15
  • I checked and find critical part of code - it is for setting style sheet on `QtableView`. I use `self.tableView.setStyleSheet(""" QTableView::item { padding-left: 10px; padding-right: 10px; } QTableView { #gridline-color: black; };""" )`. – Dave May 01 '18 at 23:26
  • Ok, thanks. Style sheets of my PyQt codes are giving me strange behavior time to time. I am a bit confused what is best practise about styles, usually on forums I found that CSS is not always good working... – Dave May 01 '18 at 23:32