原文出处:Qt 之 QHeaderView 添加复选框_qtableview添加复选框-CSDN博客
这哥们只贴了部分代码,我还是把它弄好分享给大家吧
DTableHeaderView.h
#ifndef DTABLEHEADERVIEW_H
#define DTABLEHEADERVIEW_H
#include <QHeaderView>
class DTableHeaderView : public QHeaderView
{
Q_OBJECT
public:
DTableHeaderView(Qt::Orientation orientation, QWidget *parent);
signals:
void stateChanged(int state);
public slots:
void setStateChanged(int state);
protected:
void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const;
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
bool event(QEvent *event);
private:
bool m_bPressed = false;
bool m_bChecked = false;
bool m_bTristate = false;
bool m_bNoChange = false;
bool m_bMoving = false;
const int CHECK_BOX_COLUMN = 0;
};
#endif // DTABLEHEADERVIEW_H
DTableHeaderView.cpp
#include "DTableHeaderView.h"
#include <QPainter>
#include <QCheckBox>
#include <QMouseEvent>
DTableHeaderView::DTableHeaderView(Qt::Orientation orientation, QWidget *parent)
: QHeaderView(orientation, parent)
{
// setStretchLastSection(true);
setHighlightSections(false);
setMouseTracking(true);
// 响应鼠标
setSectionsClickable(true);
}
// 槽函数,用于更新复选框状态
void DTableHeaderView::setStateChanged(int state)
{
if (state == Qt::PartiallyChecked)
{
m_bTristate = true;
m_bNoChange = true;
}
else
{
m_bNoChange = false;
}
m_bChecked = (state != Qt::Unchecked);
update();
}
// 绘制复选框
void DTableHeaderView::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;
}
QCheckBox checkBox;
option.iconSize = QSize(20, 20);
option.rect = rect;
style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter, &checkBox);
//style()->drawItemPixmap(painter, rect, Qt::AlignCenter, QPixmap(":/images/checkBoxChecked"));
//style()->drawControl(QStyle::CE_CheckBox, &option, painter, this);
}
}
// 鼠标按下表头
void DTableHeaderView::mousePressEvent(QMouseEvent *event)
{
int nColumn = logicalIndexAt(event->pos());
if ((event->buttons() & Qt::LeftButton) && (nColumn == CHECK_BOX_COLUMN))
{
m_bPressed = true;
}
else
{
QHeaderView::mousePressEvent(event);
}
}
// 鼠标从表头释放,发送信号,更新model数据
void DTableHeaderView::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);
}
else
{
QHeaderView::mouseReleaseEvent(event);
}
m_bPressed = false;
}
// 鼠标滑过、离开,更新复选框状态
bool DTableHeaderView::event(QEvent *event)
{
updateSection(0); // 很关键,不然checkbox刷新有延迟!
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);
}
MainWindow.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "DTableHeaderView.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_pMode = new QStandardItemModel(this);
ui->tableView->setModel(m_pMode);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection); //设置选择模式,选择单行
ui->tableView->verticalHeader()->setVisible(false);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // Qt QTableView数据列宽度自适应, 横向填满表格
QStringList strHeaders;
strHeaders.append("");
strHeaders.append(tr("列2"));
strHeaders.append(tr("列3"));
m_pMode->setColumnCount(strHeaders.size());
m_pMode->setHorizontalHeaderLabels(strHeaders);
// 创建自定义的表头,并将其设置为表头视图
DTableHeaderView *header = new DTableHeaderView(Qt::Horizontal, ui->tableView);
ui->tableView->setHorizontalHeader(header);
QObject::connect(header, &DTableHeaderView::stateChanged, [=](int checked)
{
// 在这里处理复选框状态变化的逻辑
qDebug() << "CheckBox is" << (checked ? "checked" : "unchecked");
});
m_pMode->setRowCount(4);
for (int row = 0; row < m_pMode->rowCount(); ++row)
{
for (int col = 0; col < m_pMode->columnCount(); ++col)
{
QModelIndex index = m_pMode->index(row, col);
m_pMode->setData(index, "Row " + QString::number(row) + ", Column " + QString::number(col));
}
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
((DTableHeaderView *)ui->tableView->horizontalHeader())->setStateChanged(Qt::PartiallyChecked);
}
void MainWindow::on_pushButton_2_clicked()
{
((DTableHeaderView *)ui->tableView->horizontalHeader())->setStateChanged(Qt::Checked);
}
void MainWindow::on_pushButton_3_clicked()
{
((DTableHeaderView *)ui->tableView->horizontalHeader())->setStateChanged(Qt::Unchecked);
}