QTableWidget插入QCheckBox复选框

头文件

#ifndef CHECKBOXHEADERVIEW_H
#define CHECKBOXHEADERVIEW_H

#include <QHeaderView>

class CheckBoxHeaderView : public QHeaderView
{
    Q_OBJECT
public:
    explicit CheckBoxHeaderView(Qt::Orientation orientation, QWidget *parent = nullptr);
    ~CheckBoxHeaderView();

protected:
    bool event(QEvent *event);
    void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const;
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

public slots:
    void onStateChanged(int state);

private:
    bool m_bPressed;
    bool m_bChecked;
    bool m_bTristate;
    bool m_bNoChange;
    bool m_bMoving;

signals:
    void stateChanged(int state);

};

#endif // CHECKBOXHEADERVIEW_H
 

源文件

#include "checkboxheaderview.h"
#include <QPainter>
#include <QMouseEvent>
#include <QCheckBox>

#define CHECK_BOX_COLUMN 1

CheckBoxHeaderView::CheckBoxHeaderView(Qt::Orientation orientation, QWidget *parent)
    : QHeaderView(orientation, parent),//m_isOn(false),
      m_bPressed(false),
      m_bChecked(false),
      m_bTristate(false),
      m_bNoChange(false),
      m_bMoving(false)
{
    setSectionsClickable(true);
}

CheckBoxHeaderView::~CheckBoxHeaderView()
{

}

void CheckBoxHeaderView::onStateChanged(int state)
{
    if (state == Qt::PartiallyChecked) {
        m_bTristate = true;
        m_bNoChange = true;
    }
    else {
        m_bNoChange = false;
    }

    m_bChecked = (state != Qt::Unchecked);
    update();
}

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

    if (logicalIndex == CHECK_BOX_COLUMN)//第一列
    {
        QStyleOptionButton option;
        option.initFrom(this);

        if (m_bChecked)
            option.state |= QStyle::State_Sunken;

        if (m_bTristate && m_bNoChange)
            option.state |= QStyle::State_NoChange;
        else
            option.state |= m_bChecked ? QStyle::State_On : QStyle::State_Off;
        if (testAttribute(Qt::WA_Hover) && underMouse()) {
            if (m_bMoving)
                option.state |= QStyle::State_MouseOver;
            else
                option.state &= ~QStyle::State_MouseOver;
        }

        QPalette palette;
        palette.setColor(QPalette::Background, QColor(0,0,0,100));
        QCheckBox checkBox;
        option.iconSize = QSize(20, 20);
        option.rect = QRect(rect.left()+(rect.width()-checkBox.sizeHint().width())/2,
                            rect.top()+(rect.height()-checkBox.sizeHint().height())/2,
                            checkBox.sizeHint().width(), checkBox.sizeHint().height());
//        style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter, &checkBox);
        option.palette = palette;
        style()->drawControl(QStyle::CE_CheckBox, &option, painter, &checkBox);
    }

}

void CheckBoxHeaderView::mousePressEvent(QMouseEvent *event)
{
    int nColumn = logicalIndexAt(event->pos());
    if ((event->buttons() & Qt::LeftButton) && (nColumn == CHECK_BOX_COLUMN))
    {
        m_bPressed = true;
    }
    else
    {
        QHeaderView::mousePressEvent(event);
    }
}

void CheckBoxHeaderView::mouseReleaseEvent(QMouseEvent *event)
{
    if (m_bPressed)
    {
        if (m_bTristate && m_bNoChange)
        {
            m_bChecked = true;
            m_bNoChange = false;
        }
        else
        {
            m_bChecked = !m_bChecked;
        }

        update();

        Qt::CheckState state = m_bChecked ? Qt::Checked : Qt::Unchecked;

        emit stateChanged(state);

        updateSection(CHECK_BOX_COLUMN);
    }
    else
    {
        QHeaderView::mouseReleaseEvent(event);
    }

    m_bPressed = false;
}

bool CheckBoxHeaderView::event(QEvent *event)
{
//    updateSection(0);
//    if (event->type() == QEvent::Enter || event->type() == QEvent::Leave)
//    {
//        QMouseEvent *pEvent = static_cast<QMouseEvent *>(event);
//        int nColumn = logicalIndexAt(pEvent->x());
//        if (nColumn == CHECK_BOX_COLUMN)
//        {
//            m_bMoving = (event->type() == QEvent::Enter);

//            update();
//            return true;
//        }
//    }
    return QHeaderView::event(event);
}

添加样式

checkBox.setProperty("stylesheet","default");

样式qss

QCheckBox[stylesheet='default']
{
    color: white;
    background: transparent;
}
QCheckBox[stylesheet='default']::indicator:disabled:unchecked,
QCheckBox[stylesheet='default']::indicator:enabled:unchecked
{
    image: url(:/assets/images/icon_options.png);
}
QCheckBox[stylesheet='default']::indicator:disabled:checked,
QCheckBox[stylesheet='default']::indicator:enabled:checked
{
    image: url(:/assets/images/icon_selected.png);
}

使用示例

CheckBoxHeaderView* checkBoxHeader = new CheckBoxHeaderView(Qt::Horizontal, ui->tableWidget);
    checkBoxHeader->setStretchLastSection(true);
    checkBoxHeader->setStyleSheet("alignment: left;");
    QObject::connect(checkBoxHeader, &CheckBoxHeaderView::stateChanged, this, &DeviceManageForm::onCheckBoxHeaderStateChanged);
    ui->tableWidget->setHorizontalHeader(checkBoxHeader);

参考文章

/**
 * QTableWidget自定义表头QHeaderView加全选复选框
 * https://blog.csdn.net/qq_43113326/article/details/101020715
 * QTableView插入QCheckBox复选框
 * https://blog.csdn.net/mj348940862/article/details/124475266
 */

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值