Quantcast
Channel: PyQt Color Based CheckBox not setting model data - Stack Overflow
Viewing all articles
Browse latest Browse all 2

PyQt Color Based CheckBox not setting model data

$
0
0

I am open to better alternatives, but what I got here is a checkbox that uses a color code of green and red instead of 'checked' and 'unchecked'.

I am using this with a custom QStyledItemDelegate, QTableView and QAbstractTableModel, with the intent of storing the state of the 'checkbox'.

The issue is the delegate setModelData is not called upon mouse press. Note that this issue is not present in any of my other custom widgets (e.g. custom QDateEdit and QLineEdit), for which I never had to do anything (in the widget code) to make the setModelData call happen.

This is why I am sure the problem is that I am missing something in this class code. My guess is a signal or the implementation of some method that defaults to a no-op in the code of QToolButton. Which one, though?

EDIT: a full example of was requested, the relevant code is ColorCheckBox, the rest is necessary to make it run. When you click on the box it should print the changed value, but aside for twice at the beginning, it does not.

from PyQt5 import QtCore, QtWidgets
import sys


def validate(value, expected_type):
    if type(value) == QtCore.QVariant:
        value = None if value.isNull() or not value.isValid() else value.value()
    if expected_type is bool and not value:
        return False
    value = expected_type() if value is None else expected_type(str(value))
    return value


class ColorCheckBox(QtWidgets.QToolButton):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.bool = False
        self.setStyleSheet("background-color: red")

    def data(self):
        return self.bool

    def set_data(self, value):
        self.set_checked(validate(value, bool))
        self.update()

    def set_checked(self, value):
        self.bool = value
        if self.bool:
            self.setStyleSheet("background-color: green")
        else:
            self.setStyleSheet("background-color: red")

    def mousePressEvent(self, event):
        super().mousePressEvent(event)
        if event.button() == QtCore.Qt.LeftButton:
            self.set_data(not self.bool)


class MyWindow(QtWidgets.QWidget):
    def __init__(self, *args):
        super().__init__(*args)
        tableview = TableView()
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(tableview)
        self.setLayout(layout)


class Delegate(QtWidgets.QStyledItemDelegate):
    def __init__(self, model):
        super().__init__()
        self.model = model

    def createEditor(self, parent, option, index):
        widget = ColorCheckBox(parent)
        widget.set_data(False)
        return widget

    def setModelData(self, widget, model, index):
        self.model.setData(index, widget.data())

    def setEditorData(self, widget, index):
        widget.set_data(index.data())


class Model(QtCore.QAbstractTableModel):
    def __init__(self, parent=None):
        QtCore.QAbstractTableModel.__init__(self, parent=parent)

    def flags(self, index):
        return super().flags(index) | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if not index.isValid() or role != QtCore.Qt.DisplayRole:
            return QtCore.QVariant()
        return QtCore.QVariant('False')

    def setData(self, index, value, role=QtCore.Qt.EditRole):
        print("data[{}][{}] = {}".format(index.row(), index.column(), value))
        return True

    def rowCount(self, parent=QtCore.QModelIndex()):
        return 1

    def columnCount(self, parent=QtCore.QModelIndex()):
        return 1


class TableView(QtWidgets.QTableView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.model = Model(self)
        delegate = Delegate(self.model)
        self.setItemDelegate(delegate)
        self.setEditTriggers(self.CurrentChanged)
        self.setModel(self.model)
        for row in range(self.model.rowCount()):
            for column in range(self.model.columnCount()):
                index = self.model.index(row, column)
                self.openPersistentEditor(index)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())


Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles





Latest Images