11
votes

QT QTableView - Alignement de la case à cocher lors de l'utilisation d'IsuserCheckable

J'utilise la case à cocher QTableView Drapeau de Qt :: ItemiSuerCheckable 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 comme textalignmentrole de la fonction de données de modèles (). xxx

Ceci n'est cependant pas alignant ma case à cocher.

Est-ce que quelqu'un sait comment utiliser les cases à cocher est ce mode?


0 commentaires

7 Réponses :


2
votes

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.


0 commentaires

2
votes

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.

rapport de bogue: http://bugreports.qt-project.org/browse/qtbug -9047

Même question avec quelques réponses: http: //lists.trolltech. COM / QT-Intérêt / 2006-06 / msg00476.html


0 commentaires

4
votes

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)


1 commentaires

2 des liens sont cassés




3
votes

solution pour python (pyside, pyqt) pour centrer la case à cocher et avec modifiable autorisé: xxx

dans votre modèle de table, assurez-vous que les indicateurs permettent à l'utilisateur de vérifier / décocher la cellule. . xxx

Enfin, définissez le booleantelagate dans votre table xxx


0 commentaires

1
votes

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);
    }
};


0 commentaires

0
votes

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))


0 commentaires