Alex
Alex

Reputation: 95

QStyledItemDelegate: Add disabled check indicator

I'm using a QTreeView with a custom QStyledItemDelegate to display various parameter items. I want all of the items to have a check indicator, however some of the Checkboxes should be disabled (but still visible and set checked!).

Here's the Delegate code:

class MyDelegate(QtWidgets.QStyledItemDelegate):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def initStyleOption(self, option, index):
        super().initStyleOption(option, index)
        option.features |= QtWidgets.QStyleOptionViewItem.HasCheckIndicator
        if index.data(MyItem.ROLE_OPTIONAL):
            #Disable check indicator here!
        

Do I have to tamper with MyDelegate.paint() to make this work?

Upvotes: 0

Views: 605

Answers (2)

musicamante
musicamante

Reputation: 48300

In case the solution provided by eyllanesc is not what the OP is looking for, I'm assuming that what is required is that the item still has a checked check box and is still enabled/editable, but the item does not have the QtCore.Qt.ItemIsUserCheckable flag set.

In that case, the solution is to subclass the model that is going to be used and return QtCore.Qt.Checked for the QtCore.Qt.CheckStateRole role.

class SomeModel(InheritedModelClass):
    def data(self, index, role=QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.CheckStateRole and self.data(index, ROLE_OPTIONAL):
            return QtCore.Qt.Checked
        return super().data(index, role)

This also works if a model subclass is already being used, as it's enough to add the first if role == condition to the currently existing data() implementation if it is overridden.

If, for any reason, the items do have the ItemIsUserCheckable flag set, the flags() function also has to be overridden:

    def flags(self, index):
        # get the flags from the default implementation
        flags = super().flags(index)
        if self.data(index, ROLE_OPTIONAL):
            # remove the checkable flag
            flags &= ~QtCore.Qt.ItemIsUserCheckable
        return flags

Upvotes: 1

eyllanesc
eyllanesc

Reputation: 243993

Assuming that when the OP says: some of the Checkboxes should be disabled (but still visible and set checked!) indicates that it shows the item as disabled and that the user cannot change the state of the checkbox then you must change the state of the QStyleOptionViewItem, on the other hand you must return false in the editorEvent method:

class StyledItemDelegate(QtWidgets.QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super().initStyleOption(option, index)

        if index.data(MyItem.ROLE_OPTIONAL):
            option.state &= ~QtWidgets.QStyle.State_Enabled

    def editorEvent(self, event, model, option, index):
        if index.data(MyItem.ROLE_OPTIONAL):
            return False
        return super().editorEvent(event, model, option, index)

Upvotes: 2

Related Questions