通过重写QHeaderView中的paintSection()方法在QTableWidget表头中某列插入复选框

 一、重写QHeaderView

        通过重写QHeaderView中的paintSection()方法来实现在QTableWidget组件的表头中插入复选框的功能。

        重写函数为:void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const override

        原理是QTableWidget使用MyHeaderView添加表头时,通过QPainter的重绘功能,在添加表头的过程中对表头列绘制复选框,并通过重写鼠标的点击事件,获取复选框的状态,通过信号和槽的方式完成想要完成的动作。

MyHeaderView.h头文件

#ifndef MyTableWidget_H
#define MyTableWidget_H


#include <QtWidgets>

class MyHeaderView : public QHeaderView
{
	Q_OBJECT
public:
	MyHeaderView(Qt::Orientation orientation,
		QWidget * parent = nullptr) :
		QHeaderView(orientation, parent)
	{
		setSectionsClickable(true);
	}

protected:
	void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const override;
	void mousePressEvent(QMouseEvent* event) override;
private:
	void checkBoxStateChanged(int pos);
signals:
	void checkBoxChangedIndex(int);
private:
	Qt::CheckState triState1 = Qt::Unchecked;
	Qt::CheckState triState2 = Qt::Unchecked;
};

#endif // MyTableWidget_H

MyHeaderView .cpp源文件


#include "MyTableWidget.h"

void MyHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
	painter->save();
	QHeaderView::paintSection(painter, rect, logicalIndex);
	painter->restore();
	if (logicalIndex == 1)
	{
		QStyleOptionButton option;
		option.initFrom(this);
		option.rect = QRect(rect.x()/* + 10*/, rect.y() + 10, 18, 18);
		option.features = QStyleOptionButton::None;
		if (triState1 == Qt::Checked)
			option.state |= QStyle::State_On;
		else if (triState1 == Qt::PartiallyChecked)
			option.state |= QStyle::State_NoChange;
		else
			option.state |= QStyle::State_Off;
		style()->drawControl(QStyle::CE_CheckBox, &option, painter/*, checkBox*/);
	}
	else if (logicalIndex == 2) {
		QStyleOptionButton option;
		option.initFrom(this);
		option.rect = QRect(rect.x()/* + 10*/, rect.y() + 10, 18, 18);
		option.features = QStyleOptionButton::None;
		if (triState2 == Qt::Checked)
			option.state |= QStyle::State_On;
		else if (triState2 == Qt::PartiallyChecked)
			option.state |= QStyle::State_NoChange;
		else
			option.state |= QStyle::State_Off;
		style()->drawControl(QStyle::CE_CheckBox, &option, painter/*, checkBox*/);
	}
}

void MyHeaderView::mousePressEvent(QMouseEvent* event)
{
	if (event->button() == Qt::LeftButton) {
		if (logicalIndexAt(event->pos()) == 1) {
			switch (triState1) {
			case Qt::Unchecked:
				triState1 = Qt::Checked;
				break;
			case Qt::Checked:
				triState1 = Qt::Unchecked;
				break;
			}
			updateSection(1);
		}
		else if (logicalIndexAt(event->pos()) == 2) {
			switch (triState2) {
			case Qt::Unchecked:
				triState2 = Qt::Checked;
				break;
			case Qt::Checked:
				triState2 = Qt::Unchecked;
				break;
			}
			updateSection(2);
		}
		checkBoxStateChanged(logicalIndexAt(event->pos()));
	}
	QHeaderView::mousePressEvent(event);
}

void MyHeaderView::checkBoxStateChanged(int pos)
{
	emit checkBoxChangedIndex(pos);
}

         paintSection()方法是QTableWidget在绘制表头的时候自动调用的,其中的logicalIndex参数为表头中的列的索引值。

        上述示例中为表头的第二列和第三列添加复选框,单独用triState1和triState2来管理,通过信号和槽传递关键信息做下一步处理

二、引用和使用

QTableWidget *qTableWidget = new QTableWidget();
qTableWidget->setColumnCount(3);
MyHeaderView *qMyHeaderView = new MyHeaderView(Qt::Horizontal, qTableWidget);
connect(qMyHeaderView, &MyHeaderView::checkBoxChangedIndex, this, &OiDataAnsysTest::changeAllColumnCheckBoxState);
qTableWidget->setHorizontalHeader(qMyHeaderView);
qTableWidget->setHorizontalHeaderLabels(QStringList() << "Column1" << "Column2" << "Column3");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值