Qt之QHeaderView添加复选框
Qt 添加 复选框
2023-09-14 08:56:50 时间
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; 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
鼠标滑过、离开,更新复选框状态。
源码过多,这里只贴更改部分及新增部分,其它部分请参考: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)));
C/C++ Qt ListWidget 列表框组件应用 ListWidget列表框组件,该组件与TreeWidget有些相似,区别在于TreeWidget可以实现嵌套以及多字段结构,而ListWidget组件则只能实现单字段结构,ListWidget组件常用于显示单条记录,例如只显示IP地址,用户名等数据,如下笔记是本人在开发中经常用到的一些基本操作技巧,包括列表框组件的基本操作方法。
相关文章
- QT从下载到安装的具体教程
- QT的基本知识「建议收藏」
- Qt Designer快速入门(python GUI 可视化界面搭建)
- Qt小站上架正则测试工具
- 来自Qt交流群的群友提问
- Qt Qml 中动态创建 & 销毁视频容器技巧(一)
- 编程在Linux下学习Qt界面编程(linux下qt界面)
- Linux串口应用开发实践——Qt篇(linux串口qt)
- 实现Linux下Qt应用静态编译的方法(linux下qt静态编译)
- 在Linux中安装Qt第三方库的指南(linux安装qt库)
- Qt蓝牙编程指南:在Linux系统上使用Qt开发蓝牙应用程序(qt蓝牙编程linux)
- Linux下高效安装Qt(linux下安装qt)
- 从零开始:Qt 编译在 Linux 上的指南(qt编译linux)
- 入门Linux下Qt编程,掌握技巧!(linux下qt编程入门)
- 使用Qt实现MySQL数据库连接教程(qt连接mysql数据库)
- 如何在Linux上运行QT程序?(linux运行qt程序)
- 深入浅出:使用Qt连接MSSQL(qt 连接mssql)