CheckBox 组件实现 教学总结
Table of Contents
- 一、这个模块到底在学什么
- 1. 状态层
- 2. 多状态层
- 3. 联动层
- 二、每个模块 / 函数的详细教学
- A. QCheckBox 详细教学
- A.1 它是什么
- QCheckBox
- QRadioButton
- A.2 这次为什么用 QCheckBox
- 用途 1:三态演示
- 用途 2:主从联动
- A.3 最核心接口
- 1. setChecked(bool)
- 2. isChecked()
- 3. setText(const QString &)
- 4. stateChanged(int)
- B. setTristate() 详细教学
- B.1 它是什么
- B.2 这次为什么必须调用它
- B.3 三态有什么实际意义
- C. Qt::Checked / Qt::PartiallyChecked / Qt::Unchecked 详细教学
- C.1 Qt::Checked
- C.2 Qt::PartiallyChecked
- C.3 Qt::Unchecked
- C.4 为什么 stateChanged(int) 用的是 int
- D. on_checkBox_stateChanged(int state) 详细教学
- D.1 它在做什么
- D.2 为什么这是一种很好的教学写法
- D.3 这里的设计思想是什么
- E. on_pushButton_clicked() 详细教学
- E.1 isCheckable() 是什么
- E.2 为什么点击按钮后文字也会变回“未选中”
- E.3 这里你应该形成的认识
- F. on_checkBox_master_stateChanged(int state) 详细教学
- F.1 它在做什么
- F.2 为什么只处理 Checked 和 Unchecked
- F.3 这是哪种典型设计模式
- F.4 这个版本还缺什么“反向联动”
- 三、本模块新增模块的重点系统讲解
- 1. QCheckBox
- 定义
- 常见场景
- 常用接口
- 本次作用
- 2. 三态机制 setTristate()
- 定义
- 三种状态
- 本次作用
- 典型应用
- 3. Qt::Checked / Qt::PartiallyChecked / Qt::Unchecked
- 定义
- 本次作用
- 典型写法
- 4. isCheckable()
- 定义
- 本次作用
- 注意
- 5. setChecked()
- 定义
- 本次作用
- 重要理解
- 四、这个模块最重要的知识点
- 1. 复选框不只是“打勾”
- 2. 状态可以是两态,也可以是三态
- 3. 主复选框控制子复选框是标准 GUI 模式
- 4. 优先修改状态,而不是直接修改表象
- 五、这个模块最容易踩的坑
- 易错点 1:没调用 setTristate()
- 易错点 2:把 stateChanged(int) 当成布尔值
- 易错点 3:主复选框和子复选框对象名写错
- 易错点 4:只改子框不改主框,误以为已经完整实现了“全选逻辑”
- 六、你现在应该形成的理解
- 七、这一模块最值得记住的最小模板
Protected content
请输入课程内容访问密码
很好。现在进入 CheckBox:阶段 2(教学总结)。
先给结论:
这个模块真正要掌握的,不只是“复选框能打勾”,而是 QCheckBox 的三种典型职责:
-
单项开关:开 / 关
-
三态选择:选中 / 半选 / 未选中
-
主从联动控制:一个主框控制多个子框
你的作业文档这次实际上把这三类用法放在一起了:
-
checkBox:演示三态; -
pushButton:把三态框强制恢复为未选中; -
checkBox_master:控制checkBox_sub_a和checkBox_sub_b的勾选状态。
所以这一节不是单纯的“控件展示”,而是已经进入了 状态管理与联动控制。
一、这个模块到底在学什么
这个模块可以拆成 3 层。
1. 状态层
复选框本质上表示一个“状态”:
-
是否启用
-
是否接受
-
是否全选
-
是否包含某项功能
所以 QCheckBox 不是“显示控件”,而是状态控件。
2. 多状态层
一般人对复选框的直觉只有两种状态:
但 Qt 允许三态:
这次你真正第一次接触的是:
“半选”不是 bug,而是合法状态。
3. 联动层
这次更重要的是:
-
一个复选框自己的状态变化;
-
一个复选框去控制其他复选框。
也就是:
这已经是典型的 GUI 状态联动模式。
二、每个模块 / 函数的详细教学
下面按你要求,把这次出现的每个重要模块、函数、枚举常量逐个详细说明。
A. QCheckBox 详细教学
A.1 它是什么
QCheckBox 是 Qt 的复选框控件。
特点是:
-
用户可以勾选 / 取消勾选
-
可表示布尔状态
-
可扩展为三态
-
可用于权限、选项、设置、主从控制等场景
它适合处理:
-
是否自动保存
-
是否记住密码
-
是否开启某功能
-
是否选择某个项目
-
是否全选
这和 QRadioButton 的区别非常重要:
QCheckBox
-
可以 0 个、1 个或多个同时选中
-
适合“独立开关”或“多选”
QRadioButton
-
一组中通常只能选 1 个
-
适合“互斥单选”
A.2 这次为什么用 QCheckBox
因为你的作业文档中有两个不同用途:
用途 1:三态演示
checkBox 用来让你看到“选中 / 半选 / 未选中”的变化
用途 2:主从联动
checkBox_master 用来控制两个子项是否全选
这两个都是 QCheckBox 非常典型的用法。
A.3 最核心接口
1. setChecked(bool)
设置勾选状态:
ui->checkBox->setChecked(false);
这次你在按钮槽和主从联动里都用到了。
2. isChecked()
判断当前是否勾选:
bool checked = ui->checkBox->isChecked();
你这次代码里没有直接用,但后面非常常见。
3. setText(const QString &)
设置复选框显示文字:
ui->checkBox->setText("未选中");
这次你把复选框本身当成了“状态提示器”,所以会动态改文字。
4. stateChanged(int)
这是这次最核心的信号。
它不是只告诉你“选没选”,而是把当前状态以 int 参数传出来。
这个 int 对应的是 Qt 的状态枚举值:
-
Qt::Unchecked -
Qt::PartiallyChecked -
Qt::Checked
B. setTristate() 详细教学
B.1 它是什么
这是这次最关键的新接口之一。
ui->checkBox->setTristate();
它的作用是:
启用三态模式
默认情况下,QCheckBox 只有两态:
调用 setTristate() 后,才会允许:
B.2 这次为什么必须调用它
因为如果你不写:
ui->checkBox->setTristate();
那么你点击复选框时只会在:
-
选中
-
未选中
之间切换,永远不会出现“半选”。
所以这一步不是优化,而是三态逻辑成立的前提。
B.3 三态有什么实际意义
“半选”通常用于表示:
-
一组子项中,只选中了一部分
-
状态不完全确定
-
某种中间状态
例如文件树、权限树、全选-部分选中这种界面里很常见。
所以这节文档先单独演示三态,是有教学目的的。
C. Qt::Checked / Qt::PartiallyChecked / Qt::Unchecked 详细教学
这三个常量是这节最重要的状态枚举。
C.1 Qt::Checked
表示:
你代码里:
if (state == Qt::Checked)
{
ui->checkBox->setText("选中");
}
C.2 Qt::PartiallyChecked
表示:
也就是三态里的中间值。
你代码里:
else if (state == Qt::PartiallyChecked)
{
ui->checkBox->setText("半选");
}
这个状态如果没有启用三态,是不会自然出现的。
C.3 Qt::Unchecked
表示:
你这次在代码里没有直接写这个枚举常量,而是用 else 兜底。
但逻辑上它对应的就是:
ui->checkBox->setText("未选中");
如果你想写得更明确,也可以写成:
else if (state == Qt::Unchecked)
{
ui->checkBox->setText("未选中");
}
C.4 为什么 stateChanged(int) 用的是 int
因为 Qt 的信号槽接口经常把枚举作为整数传递。
你收到的是 int,但在逻辑上你应该把它理解成“状态枚举值”。
也就是说:
D. on_checkBox_stateChanged(int state) 详细教学
这是本模块第一个核心槽函数。
你写的是:
void MainWindow::on_checkBox_stateChanged(int state)
{
if (state == Qt::Checked)
{
ui->checkBox->setText("选中");
}
else if (state == Qt::PartiallyChecked)
{
ui->checkBox->setText("半选");
}
else
{
ui->checkBox->setText("未选中");
}
}
D.1 它在做什么
它不是简单响应一个点击,而是在做:
根据当前复选框状态,更新自身显示文字
也就是:
D.2 为什么这是一种很好的教学写法
因为它让你看见:
-
stateChanged(int)真正传来的是什么 -
三态分别长什么样
-
槽函数可以不只是“做业务”,也可以“做状态可视化反馈”
它比只写一句 qDebug() 更直观。
D.3 这里的设计思想是什么
这是典型的:
也就是把程序内部状态,翻译成用户能看懂的文本。
以后你做设置页、权限页、导出页,这种写法很常见。
E. on_pushButton_clicked() 详细教学
这个函数负责:
用按钮强制把三态框恢复成未选中
你写的是:
void MainWindow::on_pushButton_clicked()
{
if (ui->checkBox->isCheckable())
{
ui->checkBox->setChecked(false);
}
}
E.1 isCheckable() 是什么
isCheckable() 的含义是:
这个控件当前是否“可勾选”
这在很多普通 QCheckBox 场景里几乎总是 true。
所以这里它更像一个“防御式判断”。
E.2 为什么点击按钮后文字也会变回“未选中”
因为:
ui->checkBox->setChecked(false);
会改变 checkBox 的状态;
状态一变,就会自动触发:
on_checkBox_stateChanged(int state)
于是文字也会同步变成“未选中”。
这说明 Qt 的控件联动不是你手动一层层调,而是:
这就是信号槽机制真正的价值。
E.3 这里你应该形成的认识
这次按钮不是直接“改文字”,而是:
-
改状态
-
状态触发信号
-
信号驱动文字更新
也就是说:
优先改“源状态”,不要直接改“表面结果”
这是 GUI 编程里非常重要的设计习惯。
F. on_checkBox_master_stateChanged(int state) 详细教学
这是本模块第二个核心槽函数。
你写的是:
void MainWindow::on_checkBox_master_stateChanged(int state)
{
if (state == Qt::Checked)
{
ui->checkBox_sub_a->setChecked(true);
ui->checkBox_sub_b->setChecked(true);
}
else if (state == Qt::Unchecked)
{
ui->checkBox_sub_a->setChecked(false);
ui->checkBox_sub_b->setChecked(false);
}
}
F.1 它在做什么
它表示:
主复选框是“总开关”
当主框选中:
- 两个子框一起选中
当主框取消:
- 两个子框一起取消
这就是一个最基础的“全选 / 取消全选”模式。
F.2 为什么只处理 Checked 和 Unchecked
因为这里的 checkBox_master 没启用三态,所以正常只关心两种情况:
-
Qt::Checked -
Qt::Unchecked
如果以后你把主框也改成三态,才需要进一步处理 Qt::PartiallyChecked。
F.3 这是哪种典型设计模式
这是 GUI 中非常常见的:
你以后会在这些地方不断看到它:
-
全选邮件
-
全选文件
-
全选权限项
-
统一启用/禁用某组设置
F.4 这个版本还缺什么“反向联动”
你现在实现的是:
- 主框控制子框
但还没有实现:
- 子框变化反向影响主框(比如一个子框取消时,主框变成半选)
这正是三态复选框在真实场景下很常见的高级版本。
你这次作业先做到单向联动就足够了。
三、本模块新增模块的重点系统讲解
下面是你特别要求的部分:凡是这次新出现的重要内容,都系统讲。
1. QCheckBox
定义
复选框控件,用于表示布尔或多态状态
常见场景
-
是否启用某功能
-
是否记住密码
-
权限勾选
-
全选/部分选中
常用接口
-
setChecked(bool) -
isChecked() -
setTristate() -
setText(...) -
stateChanged(int)
本次作用
-
单控件三态展示
-
主从联动控制
2. 三态机制 setTristate()
定义
让复选框从两态变成三态
三种状态
本次作用
让 checkBox 可以演示“半选”
典型应用
-
树形控件
-
批量选择
-
部分权限继承
3. Qt::Checked / Qt::PartiallyChecked / Qt::Unchecked
定义
Qt 的复选状态枚举值
本次作用
帮助你在槽函数里判断当前状态属于哪一种
典型写法
if (state == Qt::Checked) { ... }
else if (state == Qt::PartiallyChecked) { ... }
else if (state == Qt::Unchecked) { ... }
4. isCheckable()
定义
判断控件是否允许被勾选
本次作用
在按钮点击时做一个安全判断
注意
对普通 QCheckBox 来说通常一直为 true,所以这次不是核心接口,只是防御式写法。
5. setChecked()
定义
程序中直接设置勾选状态
本次作用
-
按钮强制取消选中
-
主复选框控制两个子复选框
重要理解
它不仅会改界面,还会引发相应的状态变化信号。
四、这个模块最重要的知识点
1. 复选框不只是“打勾”
它本质上是在表达一个离散状态。
2. 状态可以是两态,也可以是三态
这是这节最核心的新内容。
3. 主复选框控制子复选框是标准 GUI 模式
这不是临时技巧,而是非常通用的界面交互模式。
4. 优先修改状态,而不是直接修改表象
例如按钮点击时,不是直接改文字,而是:
这是一种正确的状态驱动写法。
五、这个模块最容易踩的坑
易错点 1:没调用 setTristate()
那就永远不会出现“半选”。
易错点 2:把 stateChanged(int) 当成布尔值
这次它不是只有 true / false,而是三种状态。
易错点 3:主复选框和子复选框对象名写错
这次对象名很多,特别容易混:
-
checkBox_master -
checkBox_sub_a -
checkBox_sub_b
易错点 4:只改子框不改主框,误以为已经完整实现了“全选逻辑”
其实你现在实现的是“单向主控”,不是“双向同步”。
六、你现在应该形成的理解
做完这个模块,你应该明确:
-
QCheckBox是状态控件 -
setTristate()可以让它支持三态 -
stateChanged(int)的参数应理解为状态枚举,而不是单纯布尔值 -
setChecked()是最常见的程序控制接口 -
“主控复选框”是 GUI 中非常常见的联动模式
七、这一模块最值得记住的最小模板
你最值得记住的是这两段:
void MainWindow::on_checkBox_stateChanged(int state)
{
if (state == Qt::Checked)
ui->checkBox->setText("选中");
else if (state == Qt::PartiallyChecked)
ui->checkBox->setText("半选");
else
ui->checkBox->setText("未选中");
}
和:
void MainWindow::on_checkBox_master_stateChanged(int state)
{
if (state == Qt::Checked)
{
ui->checkBox_sub_a->setChecked(true);
ui->checkBox_sub_b->setChecked(true);
}
else if (state == Qt::Unchecked)
{
ui->checkBox_sub_a->setChecked(false);
ui->checkBox_sub_b->setChecked(false);
}
}
它们分别代表:
以及
下一步按新流程,应该进入 ComboBox 阶段 1:实现 + 运行验证。