J'utilise la case à cocher QTableView Drapeau de Qt :: ItemiSuerCheckable em> Pour afficher une case à cocher dans une cellule de table. Après avoir lu certaines choses sur l'alignement dans une tentative de Cochez la case dans la cellule, Je retourne le qt :: aligncenter em> comme textalignmentrole de la fonction de données de modèles (). p> Ceci n'est cependant pas alignant ma case à cocher. P> Est-ce que quelqu'un sait comment utiliser les cases à cocher est ce mode? P> P>
7 Réponses :
Probablement pas la réponse que vous recherchez, mais j'ai trouvé qu'il est beaucoup plus facile de mettre en œuvre ma propre case à cocher l'article délégué lors de l'utilisation de QTableViews. P>
textalignmentrole signifie vraiment ce qu'il dit. Malheureusement, comme vous avez probablement remarqué, il ne semble pas y avoir de rôle d'alignement d'icône / widget disponible du tout. P>
rapport de bogue: http://bugreports.qt-project.org/browse/qtbug -9047 p>
Même question avec quelques réponses: http: //lists.trolltech. COM / QT-Intérêt / 2006-06 / msg00476.html P>
Après une enquête plus approfondie sur les options de délégué, j'ai trouvé une belle référence (malheureusement non disponible) et a trouvé l'hybride suivant à l'aide d'un QItemDelegate et isuserCable.
Essentiellement, vous devez prolonger qitemdelegate et répliquer, en utilisant le DrawCheck fonctionne em> fonctionner pour centrer et utiliser l'édition code> pour gérer les événements de la souris et du clavier lors de la réglage du modèle avec l'état approprié. P>
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
2 des liens sont cassés
Aussi, vous pouvez regarder ce fil: http://www.qtcentre.org / threads / 19157-QTableView-Cochez la case-Centre-avec-stylesheet? p = 181413 # Post181413 P>
solution pour python (pyside, pyqt) pour centrer la case à cocher et avec modifiable autorisé: dans votre modèle de table, assurez-vous que les indicateurs permettent à l'utilisateur de vérifier / décocher la cellule. . p> Enfin, définissez le booleantelagate code> dans votre table p>
C'est la solution que j'ai proposée. Cela suppose que vous souhaitez que la case à cocher soit la seule chose dans la cellule.
class CenteredCheckboxDelegate final : public QStyledItemDelegate { public: using QStyledItemDelegate::QStyledItemDelegate; void paint(QPainter * painter, const QStyleOptionViewItem & o, const QModelIndex & index ) const override { auto option2 = o; initStyleOption(&option2, index); auto * widget = option2.widget; auto * style = widget ? widget->style() : QApplication::style(); // Turn off all features and just draw the background option2.state.setFlag(QStyle::State_HasFocus, false); option2.features.setFlag(QStyleOptionViewItem::HasDisplay, false); option2.features.setFlag(QStyleOptionViewItem::HasDecoration, false); option2.features.setFlag(QStyleOptionViewItem::HasCheckIndicator, false); style->drawControl(QStyle::CE_ItemViewItem, &option2, painter, widget); // Then just draw the a checkbox centred in the cell option2.rect = getCheckboxRect(option2); auto stateFlag = option2.checkState == Qt::Checked ? QStyle::State_On : QStyle::State_Off; option2.state.setFlag(stateFlag, true); style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option2, painter, widget); } bool editorEvent(QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index) override { auto flags = index.flags(); if (!flags.testFlag(Qt::ItemIsUserCheckable) || !flags.testFlag(Qt::ItemIsEnabled)) { return false; } if(event->type() == QEvent::MouseButtonRelease) { auto * mouseEvent = static_cast<QMouseEvent*>(event); bool mouseOverCheckbox = getCheckboxRect(option).contains(mouseEvent->pos()); if(!mouseOverCheckbox) return false; } else if(event->type() == QEvent::KeyPress) { auto * keyEvent = static_cast<QKeyEvent*>(event); if(keyEvent->key() != Qt::Key_Space) return false; } else { return false; } auto checkState = index.data(Qt::CheckStateRole).value<Qt::CheckState>(); auto toggledCheckState = checkState == Qt::Checked ? Qt::Unchecked : Qt::Checked; return model->setData(index, toggledCheckState, Qt::CheckStateRole); } private: QRect getCheckboxRect(const QStyleOptionViewItem & option) const { auto * widget = option.widget; auto * style = widget ? widget->style() : QApplication::style(); auto checkboxSize = style->subElementRect(QStyle::SE_CheckBoxIndicator, &option, widget).size(); return QStyle::alignedRect(option.direction, Qt::AlignCenter, checkboxSize, option.rect); } };
Version PYQT5 / PYSIDE2, basée sur la version étonnante C ++ de Parker COATES
class QTableviewEditableDelegate(QStyledItemDelegate): def __init__(self, alignment: Qt.Alignment, parent: Optional[QWidget] = None): super().__init__(parent) self.alignment: Qt.Alignment = alignment self.parent = parent if self.parent: self.style = self.parent.style() else: self.style = QApplication.style() def editorEvent(self, event: QMouseEvent, model: QAbstractItemModel, option: QStyleOptionViewItem, index: QModelIndex) -> bool: checkbox_data = index.data(Qt.CheckStateRole) flags = index.flags() if not (flags & Qt.ItemIsUserCheckable) or not (flags & Qt.ItemIsEnabled) or checkbox_data is None: return False else: if event.type() == QEvent.MouseButtonRelease: mouseover_checkbox: bool = self.get_checkbox_rect(option).contains(event.pos()) if not mouseover_checkbox: return False elif event.type() == QEvent.KeyPress and event.key() != Qt.Key_Space: return False else: return False if checkbox_data == Qt.Checked: checkbox_toggled: int = Qt.Unchecked else: checkbox_toggled: int = Qt.Checked return model.setData(index, checkbox_toggled, Qt.CheckStateRole) def get_checkbox_rect(self, option: QStyleOptionViewItem) -> QRect: widget = option.widget if widget: style = widget.style() else: style = self.style() checkbox_size: QSize = style.subElementRect(QStyle.SE_CheckBoxIndicator, option, widget).size() return QStyle.alignedRect(option.direction, Qt.AlignCenter, checkbox_size, option.rect) def paint(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex): try: self.initStyleOption(option, index) painter.save() flags: Qt.ItemFlags = index.model().flags(index) widget: Optional[QWidget] = option.widget checkbox_data = index.data(Qt.CheckStateRole) if widget: style = widget.style() else: style = self.style() if option.HasCheckIndicator and checkbox_data is not None: option_checkbox = option self.initStyleOption(option_checkbox, index) option_checkbox.state = option_checkbox.state & ~QStyle.State_HasFocus option_checkbox.features = option_checkbox.features & ~QStyleOptionViewItem.HasDisplay option_checkbox.features = option_checkbox.features & ~QStyleOptionViewItem.HasDecoration option_checkbox.features = option_checkbox.features & ~QStyleOptionViewItem.HasCheckIndicator style.drawControl(QStyle.CE_ItemViewItem, option_checkbox, painter, widget) # Then just draw the a checkbox centred in the cell option_checkbox.rect = self.get_checkbox_rect(option_checkbox) if option_checkbox.checkState == Qt.Checked: state_flag = QStyle.State_On else: state_flag = QStyle.State_Off option_checkbox.state = option_checkbox.state | state_flag style.drawPrimitive(QStyle.PE_IndicatorViewItemCheck, option_checkbox, painter, widget) else: QStyledItemDelegate.paint(self, painter, option, index) painter.restore() except Exception as e: print(repr(e))