import sys
import typing

try:
    from PySide6.QtCore import QLibraryInfo, qVersion, Qt, QAbstractListModel, QModelIndex
    from PySide6.QtWidgets import QApplication, QWidget, QListView
except ImportError:
    from PySide2.QtCore import QLibraryInfo, qVersion, Qt, QAbstractListModel, QModelIndex
    from PySide2.QtWidgets import QApplication, QWidget, QListView


class ChoiceModel(QAbstractListModel):
    def __init__(self, data: typing.List[dict]) -> None:
        super().__init__()
        self._data = data

    def rowCount(self, parent: QModelIndex = QModelIndex()) -> int:
        if parent == QModelIndex():
            return len(self._data)
        return 0

    def data(self, index: QModelIndex, role: int = Qt.DisplayRole) -> typing.Any:
        if not index.isValid():
            return None
        d = self._data[index.row()]
        if role == Qt.DisplayRole:
            return d["name"]

        if role == Qt.CheckStateRole:
            checked = d["checked"]
            print('data(), row=', index.row(), ' checked=', checked)
            r = Qt.Checked if checked else Qt.Unchecked
            return r  # Workaround: int(r)

    def setData(self, index: QModelIndex, value: typing.Any, role: int = Qt.EditRole) -> bool:
        value = Qt.CheckState(value)
        print('setData(), row=', index.row(), value)
        if role != Qt.CheckStateRole:
            return False
        if index.column() > 0:
            return False
        self._data[index.row()]["checked"] = True if value == Qt.Checked else False
        self.dataChanged.emit(index, index, [role])
        return True

    def flags(self, index: QModelIndex) -> Qt.ItemFlags:
        f = super().flags(index) | Qt.ItemIsUserCheckable | Qt.ItemIsEditable
        print(f'flags(), row={index.row()}, ', f)
        return f


if __name__ == "__main__":
    print('Python {}.{}'.format(sys.version_info[0], sys.version_info[1]))
    print(QLibraryInfo.build())
    app = QApplication(sys.argv)

    view = QListView()
    view.setWindowTitle(qVersion())
    model = ChoiceModel([{"name": "test", "checked": True},
                         {"name": "test", "checked": True}])
    view.setModel(model)

    view.show()
    app.exec_()
