QHeaderView添加复选框以及样式

实现这个效果,需要重写`paintSection`来实现效果,同时重写`mousePressEvent`来执行是否勾选复选框。

paintSection实现一些复选框样式

void CheckBoxHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
    if (m_logicalIndex.contains(logicalIndex))
    {
        painter->save();
        QHeaderView::paintSection(painter, rect, logicalIndex);
        painter->restore();

        QStyleOptionButton checkBoxOption;
        QRect checkBoxRect = style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkBoxOption);
        checkBoxOption.rect = rect;
        checkBoxOption.rect.setLeft(rect.left() + (rect.width() - checkBoxRect.width()) / 2);
        checkBoxOption.rect.setTop(rect.top() + (rect.height() - checkBoxRect.height()) / 2);
        checkBoxOption.state = m_logicalIndex.value(logicalIndex) ? QStyle::State_On :QStyle::State_Off;
        checkBoxOption.state |= QStyle::State_Enabled;
        QCheckBox checkBox;
        checkBox.setStyleSheet(m_strStyleSheet);
        checkBox.style()->drawControl(QStyle::CE_CheckBox, &checkBoxOption, painter, &checkBox);
        //style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxOption, painter,&checkBox);
    }
    else
    {
        QHeaderView::paintSection(painter, rect, logicalIndex);
    }
}

或者通过QWidget的render()来实现

void CheckBoxHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
    if (m_logicalIndex.contains(logicalIndex))
    {
        painter->save();
        QHeaderView::paintSection(painter, rect, logicalIndex);
        painter->restore();

        QStyleOptionButton checkBoxOption;
        QRect checkBoxRect = style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkBoxOption);
        int x = rect.left() + (rect.width() - checkBoxRect.width()) / 2;
        int y = rect.top() + (rect.height() - checkBoxRect.height()) / 2;
        QCheckBox checkBox;
        checkBox.setCheckState(m_logicalIndex.value(logicalIndex) ?Qt::Checked:Qt::Unchecked);
        checkBox.setStyleSheet(m_strStyleSheet);
        checkBox.setGeometry(checkBoxRect);
        painter->save();
        painter->translate(x, y);
        checkBox.render(painter);
        painter->restore();
    }
    else
    {
        QHeaderView::paintSection(painter, rect, logicalIndex);
    }
}

 

mousePressEvent实现点击时是否勾选复选框

void CheckBoxHeaderView::mousePressEvent(QMouseEvent *event)
{
    if (!(event->buttons() & Qt::LeftButton)){
        QHeaderView::mousePressEvent(event);
        return ;
    }
    int idx = this->logicalIndexAt(event->pos());
    if (!m_logicalIndex.contains(idx)){
        QHeaderView::mousePressEvent(event);
        return ;
    }
    m_logicalIndex[idx] = !m_logicalIndex[idx];
    viewport()->update();
    emit stateChanged(m_logicalIndex[idx], idx);
    return;
}

 为了能够更好的设置QHeaderView中某个单元格是否拥有复选框功能,所以添加以下这些操作。

QHash<int,bool> m_logicalIndex;
signals:
    void stateChanged(bool bChecked, int index);

void CheckBoxHeaderView::setCheckable(QList<int> allIndex)
{
    bool bUpdate = false;
    for (int i=0; i<allIndex.size(); ++i)
    {
        int id = allIndex.at(i);
        if (!m_logicalIndex.contains(id)){
            m_logicalIndex[id] = false;
            bUpdate = true;
        }
    }
    if (bUpdate){
        viewport()->update();
    }
}

void CheckBoxHeaderView::setCheckable(int idx)
{
    if (!m_logicalIndex.contains(idx)){
        m_logicalIndex[idx] = false;
        viewport()->update();
    }
}

void CheckBoxHeaderView::setUncheckable(QList<int> allIndex)
{
    bool bUpdate = false;
    for (int i=0; i<allIndex.size(); ++i)
    {
        int id = allIndex.at(i);
        if (m_logicalIndex.contains(id)){
            m_logicalIndex.remove(id);
            bUpdate = true;
        }
    }
    if (bUpdate){
        viewport()->update();
    }
}

void CheckBoxHeaderView::setUncheckable(int idx)
{
    if (m_logicalIndex.contains(idx)){
        m_logicalIndex.remove(idx);
        viewport()->update();
    }
}

void CheckBoxHeaderView::setChecked(bool check, int idx)
{
    if (m_logicalIndex.contains(idx))
    {
        if (m_logicalIndex[idx] != check){
            m_logicalIndex[idx] = check;
            viewport()->update();
        }
    }
}

bool CheckBoxHeaderView::isChecked(int idx) const
{
    if (m_logicalIndex.contains(idx)) {
        return m_logicalIndex[idx];
    }
    return false;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值