Qt QTableView - Alignment of checkbox when using IsUserCheckable

前端 未结 6 2559
余生分开走
余生分开走 2021-02-20 03:42

I am using QTableView\'s checkbox flag of Qt::ItemIsUserCheckable to display a checkbox in a table cell.

After reading some things on alignment in an attempt to

6条回答
  •  感动是毒
    2021-02-20 04:09

    This is the solution I came up with. This is assuming that you want the checkbox to be the only thing in the cell.

    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(event);
                bool mouseOverCheckbox = getCheckboxRect(option).contains(mouseEvent->pos());
                if(!mouseOverCheckbox) return false;
            }
            else if(event->type() == QEvent::KeyPress)
            {
                auto * keyEvent = static_cast(event);
                if(keyEvent->key() != Qt::Key_Space) return false;
            }
            else
            {
                return false;
            }
    
            auto checkState = index.data(Qt::CheckStateRole).value();
            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);
        }
    };
    

提交回复
热议问题