Как создать qcheckbox в qtableview, который получает данные из базы данных sqlite

У меня есть QTableView, который показывает данные из базы данных sqlite. Судя по всему, я устанавливаю флажок для всех доступных строк данных. Проблема в том, что флажки нельзя установить, и при нажатии отображается следующая ошибка.

if value.toBool():
    AttributeError: 'int' object has no attribute 'toBool'

Ниже приведен код, который я получил, но не дал желаемого результата. Я хотел бы выделить строку, флажок которой был установлен.

    self.table_model3 = CheckboxSqlModel(0)
    self.table_model3.setQuery("SELECT Name, Email FROM Individuals")
    self.tableView3.setModel(self.table_model3)
    self.tableView3.horizontalHeader().setStretchLastSection(True)
    self.tableView3.setShowGrid(False)
    self.table_model3.setHeaderData(0, QtCore.Qt.Horizontal, "All")
    self.table_model3.setHeaderData(1, QtCore.Qt.Horizontal, "Client Name")
    self.table_model3.setHeaderData(2, QtCore.Qt.Horizontal, "Email Address")
    self.tableView3.setStyleSheet('QHeaderView:section{Background-color:#cdcdcd; font-family: Arial Narrow; font-size: 15px; height: 30px;}')
    self.table_model3.insertColumn(0)
    self.tableView3.setColumnWidth(0, 30)


class CheckboxSqlModel(QtSql.QSqlQueryModel):
    def __init__(self, column):
        super(CheckboxSqlModel, self).__init__()
        self.column = column
        self.checkboxes = list() #List of checkbox states
        self.first = list() #Used to initialize checkboxes

    #Make column editable
    def flags(self, index):
        flags = QtSql.QSqlQueryModel.flags(self, index)
        if index.column() == self.column:
            flags |= QtCore.Qt.ItemIsUserCheckable
        return flags

    def data(self, index, role=QtCore.Qt.DisplayRole):
        row = index.row()
        if index.column() == self.column and role == QtCore.Qt.CheckStateRole:
            #Used to initialize
            if row not in self.first :
                index = self.createIndex(row, self.column)
                self.first.append(row)
                self.checkboxes.append(False)
                return QtCore.Qt.Unchecked
            #if checked
            elif self.checkboxes[row]:
                return QtCore.Qt.Checked
            else:
                return QtCore.Qt.Unchecked
        else:
            return QtSql.QSqlQueryModel.data(self, index, role)

    def setData(self, index, value, role=QtCore.Qt.DisplayRole):
        row = index.row()
        if index.column() == self.column and role == QtCore.Qt.CheckStateRole:
            if value.toBool():
                self.checkboxes[row] = True
            else:
                self.checkboxes[row] = False
            self.dataChanged.emit(index, index)
            return True
        else:
            return False

person And3r50n 1    schedule 01.03.2018    source источник


Ответы (1)


Проблема в том, что значение преобразуется в сохраненный тип, в вашем случае это целое число, которое принимает следующие значения Qt::Checked, Qt::PartiallyChecked и Qt::Checked, решение состоит в том, чтобы сравнить их с этими значениями.

def setData(self, index, value, role=QtCore.Qt.DisplayRole):
    row = index.row()
    if index.column() == self.column and role == QtCore.Qt.CheckStateRole:
        if value == QtCore.Qt.Checked:
            self.checkboxes[row] = True
        else:
            self.checkboxes[row] = False
        self.dataChanged.emit(index, index, [QtCore.Qt.CheckStateRole])
        return True
    else:
        return False

Чтобы выбрать или отменить выбор, мы используем следующий метод

    self.table_model3.dataChanged.connect(self.on_data_changed)

def on_data_changed(self, topleft, bottomRight, roles):
    if QtCore.Qt.CheckStateRole in roles:
        row = topleft.row()
        isChecked = topleft.data(QtCore.Qt.CheckStateRole) == QtCore.Qt.Checked
        flag = QtCore.QItemSelectionModel.Select if isChecked else QtCore.QItemSelectionModel.Deselect
        for col in range(self.table_model3.columnCount()):
            ix = self.table_model3.index(row, col)
            self.tableView3.selectionModel().select(ix, flag)
person eyllanesc    schedule 01.03.2018
comment
теперь флажки установлены, но соответствующие строки не выделяются - person And3r50n 1; 01.03.2018
comment
@ And3r50n1 Объясните, что вы имеете в виду под , но соответствующие строки не выделяются? - person eyllanesc; 02.03.2018
comment
когда флажок установлен, я хотел бы, чтобы вся эта строка была выбрана - person And3r50n 1; 02.03.2018
comment
@ And3r50n1, а что будет, если ранее была выбрана другая строка? предыдущая строка не выделена или выбирается только новая строка. - person eyllanesc; 02.03.2018
comment
если предыдущая строка все еще отмечена, я хотел бы расширить выбор. - person And3r50n 1; 02.03.2018
comment
@ And3r50n1 Другими словами, вы хотите, чтобы они выбирали строки, в которых отмечены флажки, но что произойдет, если пользователь снимет флажок. Я размещу код, который будет выбирать строку, когда она отмечена, и снимать выделение, если она не отмечена, независимо от предыдущего выбора. - person eyllanesc; 02.03.2018
comment
@ And3r50n1 Я добавил новый метод, но вы должны изменить self.dataChanged.emit(index, index) на self.dataChanged.emit(index, index, (QtCore.Qt.CheckStateRole,)) в setData () - person eyllanesc; 02.03.2018
comment
я получаю следующую ошибку self.dataChanged.emit(index, index, (QtCore.Qt.CheckStateRole,)) TypeError: QAbstractItemModel.dataChanged[QModelIndex, QModelIndex, list-of-int].emit(): argument 3 has unexpected type 'tuple - person And3r50n 1; 03.03.2018
comment
спасибо за большие усилия. это решило проблему - person And3r50n 1; 04.03.2018