当前位置: 首页 > news >正文

QTableView复选框居中

目录

  • 方法一:QSS
  • 方法2:自定义复选框委托类
      • 一、构造函数 `CheckBoxDelegate()`
      • 二、`paint()` 方法
      • 三、`editorEvent()` 方法
      • 四、关键设计要点
      • 五、扩展应用场景
      • 六、代码示例(补充)

方法一:QSS

QTableView::indicator {position: relative;  /* 相对定位 */left: 50%;           /* 左边线定位到父容器中心 */
}

缺点:需要计算向右移动一定距离的left

position和left的QSS解释
在这里插入图片描述

方法2:自定义复选框委托类


#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>
#include <QStyledItemDelegate>
#include <QPainter>
#include <QStyleOptionButton>
#include <QMouseEvent>// 自定义复选框委托类
// 功能:实现在 QTableView 中居中显示复选框,并支持点击交互,结合原样式
class CheckBoxDelegate : public QStyledItemDelegate {
public:// 构造函数explicit CheckBoxDelegate(QObject* parent = nullptr): QStyledItemDelegate(parent) {} // 继承基类构造函数// 重写绘制方法void paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index) const override{// 检查当前项是否支持勾选(Qt::ItemIsUserCheckable 标志)if (index.flags() & Qt::ItemIsUserCheckable){// --- 步骤 1: 准备绘制参数 ---QStyleOptionButton checkOption; // 创建复选框的样式选项checkOption.rect = option.rect; // 初始矩形区域设为单元格区域checkOption.state = option.state; // 继承基础状态(如启用、激活状态)// 获取当前项的勾选状态Qt::CheckState checkState = static_cast<Qt::CheckState>(index.data(Qt::CheckStateRole).toInt());// 根据状态设置 QStyle 标志if (checkState == Qt::Checked) {checkOption.state |= QStyle::State_On; // 选中状态}else {checkOption.state |= QStyle::State_Off; // 未选中状态}// --- 步骤 2: 计算居中位置 ---// 获取标准复选框指示器的默认尺寸(例如 16x16)QRect checkRect = option.widget->style()->subElementRect(QStyle::SE_CheckBoxIndicator, // 获取复选框指示器区域&checkOption,                 // 传入样式选项option.widget                 // 关联的控件(用于样式计算));// 将复选框矩形中心对齐到单元格中心checkRect.moveCenter(option.rect.center());checkOption.rect = checkRect; // 更新样式选项中的矩形区域// --- 步骤 3: 绘制复选框 ---// 使用当前控件的样式绘制复选框option.widget->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, // 绘制复选框基本元素&checkOption,                 // 样式选项painter,                     // 画布option.widget                // 关联的控件(用于样式适配));}else{// 对于非勾选项,调用基类默认绘制方法(例如文本、背景等)QStyledItemDelegate::paint(painter, option, index);}}// 重写事件处理方法(实现点击交互)bool editorEvent(QEvent* event,QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index) override{// 只处理鼠标释放事件(点击完成时触发)if (event->type() == QEvent::MouseButtonRelease){QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);// --- 步骤 1: 计算复选框的实际点击区域 ---QStyleOptionButton checkOption;checkOption.rect = option.rect; // 初始区域为单元格区域// 获取标准复选框指示器的矩形(与绘制时计算方式一致)QRect checkRect = option.widget->style()->subElementRect(QStyle::SE_CheckBoxIndicator,&checkOption,option.widget);// 将矩形中心对齐到单元格中心(确保与绘制的区域一致)checkRect.moveCenter(option.rect.center());// --- 步骤 2: 判断点击是否在复选框区域内 ---if (checkRect.contains(mouseEvent->pos())){// 获取当前勾选状态Qt::CheckState currentState = static_cast<Qt::CheckState>(index.data(Qt::CheckStateRole).toInt());// 切换状态(Checked <-> Unchecked)Qt::CheckState newState = (currentState == Qt::Checked)? Qt::Unchecked: Qt::Checked;// 更新模型数据(触发视图刷新)model->setData(index, newState, Qt::CheckStateRole);return true; // 事件已处理,不再传递}}// 其他事件交由基类处理(例如键盘事件、未点击复选框区域的鼠标事件)return QStyledItemDelegate::editorEvent(event, model, option, index);}
};

在这里插入图片描述

在 Qt 的 QTableView 中,通过自定义委托类 CheckBoxDelegate 实现复选框居中显示和交互功能,其核心逻辑集中在 paint()editorEvent() 方法中。


一、构造函数 CheckBoxDelegate()

功能
继承自 QStyledItemDelegate 并初始化父类,为后续的委托操作提供基础支持。
代码解析

explicit CheckBoxDelegate(QObject* parent = nullptr): QStyledItemDelegate(parent) {}
  • 作用:通过基类构造函数传递父对象指针,确保委托与视图控件的生命周期绑定。

二、paint() 方法

核心功能
负责绘制居中显示的复选框,并根据模型数据状态(选中/未选中)更新样式。
关键步骤解析

  1. 检查可勾选性
    通过 index.flags() & Qt::ItemIsUserCheckable 判断当前项是否支持勾选,避免对非勾选项误操作。

  2. 准备绘制参数

    • 样式选项初始化:创建 QStyleOptionButton 对象,继承视图的基础状态(如控件是否启用)。
    • 状态设置:根据模型的 Qt::CheckStateRole 数据设置 QStyle::State_On(选中)或 QStyle::State_Off(未选中)标志。
  3. 计算居中位置

    QRect checkRect = option.widget->style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkOption, option.widget
    );
    checkRect.moveCenter(option.rect.center());
    
    • 子元素矩形获取:通过 QStyle::SE_CheckBoxIndicator 获取默认复选框指示器的尺寸(如 16x16)。
    • 中心对齐:将矩形中心对齐到单元格中心,确保复选框居中。
  4. 绘制复选框
    调用 QStyle::drawPrimitive() 方法,使用当前控件的样式(如 Fusion、Windows 等)绘制复选框。


三、editorEvent() 方法

核心功能
处理鼠标点击事件,实现复选框状态的切换与模型数据更新。
关键步骤解析

  1. 事件类型过滤
    仅处理 QEvent::MouseButtonRelease 事件,确保在鼠标释放时触发状态切换。

  2. 点击区域计算

    QRect checkRect = option.widget->style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkOption, option.widget
    );
    checkRect.moveCenter(option.rect.center());
    
    • 与绘制逻辑一致:使用相同的子元素矩形计算方法,确保点击区域与绘制区域完全匹配。
  3. 状态切换与模型更新

    • 获取当前状态:从模型数据中读取 Qt::CheckStateRole 的值。
    • 状态取反:切换选中(Qt::Checked)与未选中(Qt::Unchecked)状态。
    • 更新模型:通过 model->setData() 修改数据,触发视图刷新。

四、关键设计要点

  1. 样式一致性
    使用 QStyle 绘制复选框,确保与当前系统或应用程序主题兼容。

  2. 交互精准性
    通过计算点击区域与绘制区域的一致性,避免误触或点击无效的问题。

  3. 性能优化

    • 避免重复计算:仅在需要时处理勾选项的绘制和事件。
    • 模型-视图分离:通过 setData() 更新模型,符合 Qt 的模型/视图架构。

五、扩展应用场景

  1. 三态复选框
    可扩展支持 Qt::PartiallyChecked 状态,用于树形表格的父子节点联动。

  2. 动态样式调整
    结合 QSS 修改复选框颜色、尺寸,或通过重写 sizeHint() 调整单元格大小。

  3. 键盘事件支持
    editorEvent() 中处理 QEvent::KeyPress,支持空格键切换复选框状态。


六、代码示例(补充)

// 在 QTableView 中应用委托
QTableView *tableView = new QTableView();
CheckBoxDelegate *delegate = new CheckBoxDelegate(tableView );
tableView->setItemDelegate(delegate);  // 对所有列生效

或者

// 在 QTableView 中应用委托
QTableView *tableView = new QTableView();
CheckBoxDelegate *delegate = new CheckBoxDelegate(tableView );
tableView->setItemDelegateForColumn(0, delegate);  // 对第 0 列生效

相关文章:

  • K8S学习笔记01
  • uniapp+vue3+ts 使用canvas实现安卓端、ios端及微信小程序端二维码生成及下载
  • 线性代数的本质大白话理解
  • 分布式链路追踪理论
  • [ACTF2020 新生赛]Include [ACTF2020 新生赛]Exec
  • Ubuntu深度学习革命:NVIDIA-Docker终极指南与创新实践
  • python练习:求数字的阶乘
  • Ubuntu 20.04 上安装 最新版CMake 3.31.7 的详细步骤
  • Spring Boot定时任务
  • Sui 主网升级至 V1.47.1
  • Spring Boot 3与JDK 8环境下的单元测试实践指南
  • stm32week13
  • 蒋新松:中国机器人之父
  • 三小时快速上手TypeScript之枚举
  • 【知识科普】HTTPS 加密中信息的可见性详解
  • [密码学实战]SDF之设备管理类函数(一)
  • 智能物证管理系统|DW-S404全国广泛应用
  • 关系数据的可视化
  • tanstack动态路由 + router/ 目录管理方案
  • 数据分析1
  • 监狱法修订草案提请全国人大常委会会议审议
  • 为何未来的福利国家必须绿色且公平
  • 财政部下达农业生产防灾救灾资金3.76亿元,支持黄淮海等地抗旱保春播
  • 京东美团开打,苦了商家?
  • 酒店保洁员调包住客港币,海南官方通报:成立调查组赴属地调查
  • 子公司神州信息十年来首次亏损,神州控股遭国有股东广州城投派驻董事问责