网上找到 qt qtablewidget表头复选框实现案例 进行一些修改,支持多列复选框和区域选择

checkboxheaderview.h

#ifndef CHECKBOXHEADERVIEW_H
#define CHECKBOXHEADERVIEW_H

#include <QtGui>
#include <QPainter>
#include <QHeaderView>
#include <QStyleOptionButton>
#include <QStyle>
#include <QCheckBox>
#include <QEvent>


class CheckBoxHeaderView : public QHeaderView
{
    Q_OBJECT

public:
    CheckBoxHeaderView(QWidget *parent,QList<int> checkColumnIndex, int topLeft=5, QSize size=QSize(20, 20),Qt::Orientation orientation=Qt::Horizontal)
        : QHeaderView(orientation, parent)
    {
        checkColIndex = checkColumnIndex;
        this->topLeft = topLeft;
        boxSize = size;
        for(int i=0;i<checkColIndex.length();i++){isChecked.append(false);}
    }

protected:
    void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
    {
        painter->save();
        QHeaderView::paintSection(painter, rect, logicalIndex);
        painter->restore();
        if (checkColIndex.contains(logicalIndex) )
        {
            myDebugNum(logicalIndex)
            int _index=checkColIndex.indexOf(logicalIndex);
            QStyleOptionButton option;
            option.rect = QRect(rect.x()+topLeft,rect.y()+ rect.height()/2-boxSize.height()/2, boxSize.width(), boxSize.height());
            if (isChecked[_index]) {
                option.state = QStyle::State_On;
            }
            else {
                option.state = QStyle::State_Off;
            }
            //加入复选框,设置样式
            QCheckBox *check = new QCheckBox;
            QString sheet = QString("QCheckBox {width: %1px;  height: %2px;border:1px solid rgb(174,174,174);}").arg(boxSize.width()).arg(boxSize.height());
            check->setStyleSheet(sheet);
            this->style()->drawControl(QStyle::CE_CheckBox, &option, painter, check);
        }
    }

    void mousePressEvent(QMouseEvent *event)
    {
        int index=visualIndexAt(event->pos().x());
        int offsetx=event->pos().x()-this->sectionViewportPosition(index);
        if (checkColIndex.contains(index) && offsetx<(topLeft+boxSize.width()))
        {
            int _index=checkColIndex.indexOf(index);
            bool state=isChecked[_index];
            state=!state;
            isChecked[_index]=state;
            this->updateSection(index);
            emit signalCheckStateChanged(index,state);
        }
        //继承后此信号必须手动发送,否则无法响应
        emit QHeaderView::sectionClicked(index);
        QHeaderView::mousePressEvent(event);
    }

private:
    QList<int> checkColIndex;  //表头列下标
    int  topLeft;        //勾选框起始屏幕坐标
    QSize   boxSize;        //勾选框大小
    QList<bool> isChecked;      //勾选框状态

public:
    void setCheckState(int index,bool state){
        if(checkColIndex.contains(index)){
            int _index=checkColIndex.indexOf(index);
            isChecked[_index]=state;
        }
    }

signals:
    void signalCheckStateChanged(int index,bool state);   //勾选状态发生改变信号
};

#endif // CHECKBOXHEADERVIEW_H

/*
    QStringList labellist;labellist<<"check1"<<"test1"<<"check2"<<"test2"<<"check3"<<"test3"<<"check4"<<"test4"<<"test5";
    QList<int> checklist;checklist<<0<<2<<4<<6;
    CheckBoxHeaderView *header = new CheckBoxHeaderView(this,checklist);
    ui->tableWidget->setColumnCount(labellist.length());
    ui->tableWidget->setHorizontalHeaderLabels(labellist);
    ui->tableWidget->setHorizontalHeader(header);


    ui->tableWidget->setRowCount(50);
    for(int i=0;i<50;i++){
        for(int j=0;j<labellist.length();j++){
            if(checklist.contains(j)){
                QTableWidgetItem *checkBoxItem = new QTableWidgetItem();
                checkBoxItem->setCheckState(Qt::Unchecked);
                checkBoxItem->setTextAlignment(Qt::AlignCenter);
                ui->tableWidget->setItem(i, j, checkBoxItem);
            }
            else{
                QTableWidgetItem *item = new QTableWidgetItem(QString("ceshi:%1_%2").arg(i).arg(j));
                item->setTextAlignment(Qt::AlignCenter);
                ui->tableWidget->setItem(i, j, item);
            }
        }
    }

    connect(header, &CheckBoxHeaderView::signalCheckStateChanged, [=](int index,bool state)
    {
        for(int i=0;i<ui->tableWidget->rowCount();i++){
            if(state){ui->tableWidget->item(i,index)->setCheckState(Qt::Checked);}
            else{ui->tableWidget->item(i,index)->setCheckState(Qt::Unchecked);}
        }
    });
*/


posted @ 2025-04-24 14:04  小城熊儿  阅读(83)  评论(0)    收藏  举报