Qt之QHeaderView添加复选框
简述
前面分享了QTableView中如何添加复选框。本节主要介绍QTableView中的表头-QHeaderView添加复选框的功能,下面以水平表头为例,垂直表头类似!
效果
QHeaderView
源码
TableHeaderView::TableHeaderView(Qt::Orientation orientation, QWidget *parent)
: QHeaderView(orientation, parent),
m_bPressed(false),
m_bChecked(false),
m_bTristate(false),
m_bNoChange(false),
m_bMoving(false)
{
// setStretchLastSection(true);
setHighlightSections(false);
setMouseTracking(true);
// 响应鼠标
setSectionsClickable(true);
}
// 槽函数,用于更新复选框状态
void TableHeaderView::onStateChanged(int state)
{
if (state == Qt::PartiallyChecked) {
m_bTristate = true;
m_bNoChange = true;
} else {
m_bNoChange = false;
}
m_bChecked = (state != Qt::Unchecked);
update();
}
// 绘制复选框
void TableHeaderView::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 TableHeaderView::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 TableHeaderView::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 TableHeaderView::event(QEvent *event)
{
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);
}
接口说明
onStateChanged
槽函数,与model关联,当model的数据发生变化时,表头复选中状态也随之变化。paintSection
绘制部分,主要用于绘制复选框,主要设置QStyleOptionButton的状态,然后通过QStyle的drawPrimitive绘制样式。mousePressEvent
鼠标按下表头,设置被按下的标志为true。mouseReleaseEvent
鼠标从表头释放,发送信号,更新model数据。event
鼠标滑过、离开,更新复选框状态。
QAbstractTableModel
源码
源码过多,这里只贴更改部分及新增部分,其它部分请参考:Qt之QTableView添加复选框(QAbstractItemDelegate)
// 设置表格项数据
bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid())
return false;
int nColumn = index.column();
FileRecord record = m_recordList.at(index.row());
switch (role)
{
case Qt::DisplayRole:
{
if (nColumn == File_PATH_COLUMN)
{
record.strFilePath = value.toString();
m_recordList.replace(index.row(), record);
emit dataChanged(index, index);
return true;
}
}
case Qt::CheckStateRole:
case Qt::UserRole:
{
if (nColumn == CHECK_BOX_COLUMN)
{
record.bChecked = value.toBool();
m_recordList.replace(index.row(), record);
emit dataChanged(index, index);
if (role == Qt::UserRole)
onStateChanged();
return true;
}
}
default:
return false;
}
return false;
}
// 复选状态改变,通知表头更新复选状态
void TableModel::onStateChanged()
{
Qt::CheckState state = Qt::Unchecked;
int nCount = m_recordList.count();
int nSelectedCount = 0;
FileRecord record;
for (int i = 0; i < nCount; ++i)
{
record = m_recordList.at(i);
if (record.bChecked)
++nSelectedCount;
}
if (nSelectedCount >= nCount)
{
state = Qt::Checked;
}
else if (nSelectedCount > 0)
{
state = Qt::PartiallyChecked;
}
emit stateChanged(state);
}
// 接收表头复选状态更新变化,修改表格复选状态
void TableModel::onStateChanged(int state)
{
QModelIndex index;
for (int i = 0; i < rowCount(); ++i)
{
index = this->index(i, CHECK_BOX_COLUMN);
setData(index, state == Qt::Checked, Qt::CheckStateRole);
}
}
接口说明
setData
设置表格项数据,关键代码:当role为Qt::UserRole时候,会调用onStateChanged()函数,来更新表头!onStateChanged
复选状态改变,通知表头更新复选状态。onStateChanged(int state)
槽函数,接收表头复选状态更新变化,修改表格复选状态。
使用
这时,就需要将header与model的信号与槽关联起来,更新复选框状态了!
QTableView *pTableView = new QTableView(this);
TableModel *pModel = new TableModel(this);
TableHeaderView *pHeader = new TableHeaderView(Qt::Horizontal, this);
CheckBoxDelegate *pDelegate = new CheckBoxDelegate(this);
pTableView->setHorizontalHeader(pHeader);
pTableView->setModel(pModel);
pTableView->setItemDelegate(pDelegate);
connect(pModel, SIGNAL(stateChanged(int)), pHeader, SLOT(onStateChanged(int)));
connect(pHeader, SIGNAL(stateChanged(int)), pModel, SLOT(onStateChanged(int)));
Qt之QHeaderView添加复选框的更多相关文章
- Qt之QHeaderView加入复选框
简述 前面分享了QTableView中怎样加入复选框. 本节主要介绍QTableView中的表头-QHeaderView加入复选框的功能,以下以水平表头为例.垂直表头相似! 简述 效果 QHeader ...
- Qt之QTableView添加复选框(QAbstractItemDelegate)
简述 上节分享了使用自定义模型QAbstractTableModel来实现复选框.下面我们来介绍另外一种方式: 自定义委托-QAbstractItemDelegate. 简述 效果 QAbstract ...
- Qt之QTableView添加复选框(QAbstractTableModel)
简述 使用QTableView,经常会遇到复选框,要实现一个好的复选框,除了常规的功能外,还应注意以下几点: 三态:不选/半选/全选 自定义风格(样式) 下面我们介绍一下常见的实现方式: 编辑委托. ...
- 组合框里添加复选框的方法(使用勾选的假象,用图片代替而已,并非QT原生支持)
组合框可以看作是列表框和文本框的组合,因其占据的空间少,使用操作方便,常被界面设计人员用于界面开发设计中,在有限个输入的条件下,组合框常用来代替文本框,这样从用户使用角度来看,更趋人性化,所见即所得. ...
- QListWidget的QComboBox下拉列表添加复选框及消息处理
要在QComboBox下拉列表项中添加复选框,并进行消息处理,在网上搜索了很久没有找到太多有用的信息和实际的例子,但从中还是找到了一些提示性的资料,根据这些简短的介绍,最终实现了这个功能. QComb ...
- 雷林鹏分享:jQuery EasyUI 数据网格 - 添加复选框
jQuery EasyUI 数据网格 - 添加复选框 本实例演示如何放置一个复选框列到数据网格(DataGrid).通过复选框,用户将可以选择 选中/取消选中 网格行数据. 为了添加一个复选框列,我们 ...
- dojo:为数据表格添加复选框
一.添加复选框 此时应该选用EnhancedGrid,而不是普通的DataGrid.添加复选框需要设置EnhancedGrid的plugins属性,如下: gridLayout =[{ default ...
- DateGridView标题列头添加复选框
第一:添加列标题时,添加两个空格——用于显示复选框: 第二:实现列标题添加复选框,代码如下: private void AddCheckeBoxToDGVHeader(DataGridView dgv ...
- Jquery Datatable添加复选框,实现批量操作。
最近一段时间,一直在写前端的东西,自己也不擅长,最近也有所长进,把工作中用到的一些前端知识整理一下,下次用到就不用再找了.这次主要是在datatable中添加复选框,然后实现批量操作的功能.因为是公司 ...
随机推荐
- spring mvc Controller与jquery Form表单提交代码demo
1.JSP表单 <% String basePath = request.getScheme() + "://" + request.getServerName() +&qu ...
- Grid分组汇总
Ext.onReady(function () { Ext.define('personInfo', { extend: 'Ext. ...
- 【面试题042】翻转单词顺序VS左旋转字符串
[面试题042]翻转单词顺序VS左旋转字符串 题目一: 输入一个英文句子,反转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理. 例如输入字符串“I a ...
- POJ 2142 The Balance (解不定方程,找最小值)
这题实际解不定方程:ax+by=c只不过题目要求我们解出的x和y 满足|x|+|y|最小,当|x|+|y|相同时,满足|ax|+|by|最小.首先用扩展欧几里德,很容易得出x和y的解.一开始不妨令a& ...
- java EE 5 Libraries 删掉后怎么重新导入
(1)Add Library 中 MyEclipse Libraries (2)输入 java 即可找到 问题解决.
- POJ 3034 Whac-a-Mole(DP)
题目链接 题意 : 在一个二维直角坐标系中,有n×n个洞,每个洞的坐标为(x,y), 0 ≤ x, y < n,给你一把锤子可以打到地鼠,最开始的时候,你可以把锤子放在任何地方,如果你上一秒在( ...
- poj 2762(强连通+判断链)
题目链接:http://poj.org/problem?id=2762 思路:首先当然是要缩点建新图,由于题目要求是从u->v或从v->u连通,显然是要求单连通了,也就是要求一条长链了,最 ...
- DP+矩阵快速幂 HDOJ 5318 The Goddess Of The Moon
题目传送门 /* DP::dp[i][k] 表示选择i个字符串,最后一次是k类型的字符串,它由sum (dp[i-1][j]) (a[j], a[k] is ok)累加而来 矩阵快速幂:将n个字符串看 ...
- sql openxml sp_xml_preparedocument xml 中文乱码
DECLARE @xmlText xml ,@idoc int set @xmlText = (select doc from openrowset(bulk 'C:\Word\SRC\WebApp\ ...
- lintcode:线段树的修改
线段树的修改 对于一棵 最大线段树, 每个节点包含一个额外的 max 属性,用于存储该节点所代表区间的最大值. 设计一个 modify 的方法,接受三个参数 root. index 和 value.该 ...