|
| 1 | +""" |
| 2 | + Copyright 2015 University of Auckland |
| 3 | +
|
| 4 | + Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | + you may not use this file except in compliance with the License. |
| 6 | + You may obtain a copy of the License at |
| 7 | +
|
| 8 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +
|
| 10 | + Unless required by applicable law or agreed to in writing, software |
| 11 | + distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | + See the License for the specific language governing permissions and |
| 14 | + limitations under the License. |
| 15 | +""" |
| 16 | +from PySide6 import QtCore, QtWidgets |
| 17 | + |
| 18 | + |
| 19 | +class CheckBoxDelegate(QtWidgets.QStyledItemDelegate): |
| 20 | + |
| 21 | + def __init__(self, parent=None): |
| 22 | + super(CheckBoxDelegate, self).__init__(parent) |
| 23 | + |
| 24 | + def createEditor(self, parent, option, index): |
| 25 | + return None |
| 26 | + # return QtWidgets.QCheckBox(parent) |
| 27 | + |
| 28 | + def paint(self, painter, option, index): |
| 29 | + checked = bool(index.model().data(index, QtCore.Qt.ItemDataRole.DisplayRole)) |
| 30 | + check_box_style_option = QtWidgets.QStyleOptionButton() |
| 31 | + |
| 32 | + editable = (index.flags() & QtCore.Qt.ItemFlag.ItemIsEditable) == QtCore.Qt.ItemFlag.ItemIsEditable |
| 33 | + if editable: |
| 34 | + check_box_style_option.state |= QtWidgets.QStyle.StateFlag.State_Enabled |
| 35 | + else: |
| 36 | + check_box_style_option.state |= QtWidgets.QStyle.StateFlag.State_ReadOnly |
| 37 | + |
| 38 | + if checked: |
| 39 | + check_box_style_option.state |= QtWidgets.QStyle.StateFlag.State_On |
| 40 | + else: |
| 41 | + check_box_style_option.state |= QtWidgets.QStyle.StateFlag.State_Off |
| 42 | + |
| 43 | + check_box_style_option.rect = option.rect |
| 44 | + |
| 45 | + QtWidgets.QApplication.style().drawControl(QtWidgets.QStyle.ControlElement.CE_CheckBox, check_box_style_option, painter) |
| 46 | + |
| 47 | + def editorEvent(self, event, model, option, index): |
| 48 | + ''' |
| 49 | + Change the data in the model and the state of the checkbox |
| 50 | + if the user presses the left mousebutton or presses |
| 51 | + Key_Space or Key_Select and this cell is editable. Otherwise do nothing. |
| 52 | + ''' |
| 53 | + editable = (index.flags() & QtCore.Qt.ItemFlag.ItemIsEditable) == QtCore.Qt.ItemFlag.ItemIsEditable |
| 54 | + if not editable: |
| 55 | + return False |
| 56 | + |
| 57 | + # Do not change the checkbox-state |
| 58 | + event_type = event.type() |
| 59 | + if event_type == QtCore.QEvent.MouseButtonRelease or event_type == QtCore.QEvent.MouseButtonDblClick: |
| 60 | + if event.button() != QtCore.Qt.MouseButton.LeftButton or not option.rect.contains(event.pos()): |
| 61 | + return False |
| 62 | + if event_type == QtCore.QEvent.MouseButtonDblClick: |
| 63 | + return True |
| 64 | + elif event_type == QtCore.QEvent.KeyPress: |
| 65 | + if event_type != QtCore.Qt.Key.Key_Space and event_type != QtCore.Qt.Key.Key_Select: |
| 66 | + return False |
| 67 | + else: |
| 68 | + return False |
| 69 | + |
| 70 | + # Change the checkbox-state |
| 71 | + self.setModelData(None, model, index) |
| 72 | + return True |
| 73 | + |
| 74 | + def setEditorData(self, editor, index): |
| 75 | + data = index.model().data(index, QtCore.Qt.ItemDataRole.DisplayRole) |
| 76 | + if data is not None: |
| 77 | + editor.setChecked(data) |
| 78 | + |
| 79 | + def setModelData(self, editor, model, index): |
| 80 | + value = index.model().data(index, QtCore.Qt.ItemDataRole.DisplayRole) |
| 81 | + model.setData(index, value, QtCore.Qt.ItemDataRole.EditRole) |
| 82 | + |
| 83 | + def updateEditorGeometry(self, editor, option, index): |
| 84 | + editor.setGeometry(option.rect) |
0 commit comments