最近发现在QTableWidget的表头中加入复选框这个需求较为普遍,网上相关的资料却很少,实现此功能所需相关的Qt方法也较为冷门,特作此分享。
主要实现方法为重写QHeaderView类的*void paintSection(QPainter painter, const QRect &rect, int logicalIndex) const; 函数和 *void mousePressEvent(QMouseEvent event); 函数,下面直接贴完整代码和示例,方便大家使用。
1.头文件如下:
#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(int checkColumnIndex, QPoint topLeft, QSize size,
Qt::Orientation orientation, QWidget *parent = nullptr);
protected:
void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const;
void mousePressEvent(QMouseEvent *event);
private:
int checkColIndex; //表头列下标
QPoint topLeft; //勾选框起始屏幕坐标
QSize boxSize; //勾选框大小
bool isChecked; //勾选框状态
public:
void setCheckState(bool state); //设置复选框状态
signals:
void signalCheckStateChanged(bool state); //勾选状态发生改变信号
};
#endif // CHECKBOXHEADERVIEW_H
2.cpp文件如下:
#include "checkboxheaderview.h"
CheckBoxHeaderView::CheckBoxHeaderView(int checkColumnIndex, QPoint topLeft, QSize size, Qt::Orientation orientation, QWidget *parent) : QHeaderView(orientation, parent)
{
checkColIndex = checkColumnIndex;
this->topLeft = topLeft;
boxSize = size;
isChecked = false;
}
void CheckBoxHeaderView::setCheckState(bool state)
{
isChecked = state;
}
void CheckBoxHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
painter->save();
QHeaderView::paintSection(painter, rect, logicalIndex);
painter->restore();
if (logicalIndex == checkColIndex)
{
QStyleOptionButton option;
option.rect = QRect(topLeft.x(), topLeft.y(), boxSize.width(), boxSize.height());
if (isChecked)
{
option.state = QStyle::State_On;
}
else
{
option.state = QStyle::State_Off;
}
//加入复选框,设置样式
QCheckBox *check = new QCheckBox;
QString sheet = QString("QCheckBox::indicator {width: %1px; height: %2px;}").arg(boxSize.width()).arg(boxSize.height());
check->setStyleSheet(sheet);
this->style()->drawControl(QStyle::CE_CheckBox, &option, painter, check);
}
}
void CheckBoxHeaderView::mousePressEvent(QMouseEvent *event)
{
if (visualIndexAt(event->pos().x()) == checkColIndex)
{
isChecked = !isChecked;
this->updateSection(checkColIndex);
emit signalCheckStateChanged(isChecked);
}
//继承后此信号必须手动发送,否则无法响应
emit QHeaderView::sectionClicked(visualIndexAt(event->pos().x()));
QHeaderView::mousePressEvent(event);
}
3.使用示例:
CheckBoxHeaderView *header = new CheckBoxHeaderView(0, QPoint(10, 5), QSize(20, 20), Qt::Horizontal, this);
ui->tableWidget->setColumnCount(2);
ui->tableWidget->setHorizontalHeaderLabels(QStringList() << "复选框" << "无复选框");
ui->tableWidget->setHorizontalHeader(header);
connect(header, &CheckBoxHeaderView::signalCheckStateChanged, [=](bool state)
{
qDebug() << "勾选状态:" << state;
});
效果图:
什么?!你说懒得复制粘贴?OKOK,我上传demo,设置0积分,csdn系统会自动改积分,有积分的就直接下载,没积分的再@我。
点击这里去下载demo