复选框组 CheckboxGroup
有时候你需要展示一组相关的选项,比如"兴趣爱好"(多选)或者"性别"(单选)。一个个写 Checkbox() 当然可以,但 HiEasyX 提供了更方便的 CheckboxGroup() 和 CheckboxGroupSingle(),让你用一份数据配置就能渲染出一整组复选框。
CheckboxGroupSingle():单选组,同一时间只能选中一个,就像传统的 Radio Button。CheckboxGroup():多选组,每个选项独立,可以同时选中多个。
函数原型
// 单选组
void CheckboxGroupSingle(const HXString &Title, CheckboxGroupProfile &Profile, bool SameLine = false);
// 多选组
void CheckboxGroup(const HXString &Title, CheckboxGroupProfile &Profile, bool SameLine = false);
参数说明
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Title | const HXString & | — | 整组复选框的标题文字。 |
Profile | CheckboxGroupProfile & | — | 复选框组的配置结构体。必须是 static 或全局变量。 |
SameLine | bool | false | 是否在同一行横向排列。false 表示纵向排列。 |
返回值
两个函数都没有返回值。选中状态保存在 Profile.MappingStatus 中。
CheckboxGroupProfile 结构体
| 字段 | 类型 | 说明 |
|---|---|---|
MappingStatus | std::map<HXString, CheckboxProfile> | 以选项文字为键,每个选项对应一个 CheckboxProfile。由框架自动维护,也可以被你读取。 |
MappingStatus 是一个 std::map,键是 HXString(选项文字),值是 CheckboxProfile。你可以通过 profile.MappingStatus[HXStr("选项名")].Checked 来读取某个选项的选中状态。不过要注意,如果键不存在,map 会自动插入一个默认值。
基本用法
纵向多选组
static HX::CheckboxGroupProfile groupProfile;
HX::CheckboxGroup(HXStr("兴趣爱好"), groupProfile);
// 检查某个选项是否被选中
if (groupProfile.MappingStatus[HXStr("编程")].Checked) {
// 用户选了"编程"
}
横向单选组
static HX::CheckboxGroupProfile singleProfile;
HX::CheckboxGroupSingle(HXStr("难度"), singleProfile, true); // SameLine = true
// 单选组保证只有一个被选中的
if (singleProfile.MappingStatus[HXStr("困难")].Checked) {
// 困难模式
}
CheckboxGroupProfile 必须是 static 或全局变量。如果写成局部变量,所有子选项的选中状态都会在下一帧丢失,组里永远没有任何勾选!
SameLine 横向排列
默认情况下,复选框组是纵向排列的,每个选项独占一行。如果你希望它们像工具栏按钮一样横着排,把 SameLine 设为 true:
static HX::CheckboxGroupProfile profile;
HX::CheckboxGroupSingle(HXStr("对齐方式"), profile, true);
// 会渲染成:[左对齐] [居中] [右对齐] 横向一排
SameLine = true 时,框架会尝试把所有选项放在同一行。如果文字太长、窗口太窄,可能会超出边界。这种情况下建议缩短选项文字,或者改用纵向排列。
预设默认选中
你可以在初始化时预设某些选项为选中状态:
static HX::CheckboxGroupProfile profile;
profile.MappingStatus[HXStr("音效")].Checked = true;
profile.MappingStatus[HXStr("自动保存")].Checked = true;
HX::CheckboxGroup(HXStr("游戏设置"), profile);
对于单选组,预设多个为 true 会导致只有最后一个生效(框架会自动确保单选逻辑),所以最好还是只设一个:
static HX::CheckboxGroupProfile singleProfile;
singleProfile.MappingStatus[HXStr("普通")].Checked = true;
HX::CheckboxGroupSingle(HXStr("难度"), singleProfile);
读取和响应变化
复选框组没有"返回值告诉你哪个变了",你需要在每一帧检查你关心的选项状态:
static HX::CheckboxGroupProfile profile;
HX::CheckboxGroup(HXStr("权限设置"), profile);
// 每一帧都检查
bool canRead = profile.MappingStatus[HXStr("读取")].Checked;
bool canWrite = profile.MappingStatus[HXStr("写入")].Checked;
bool canDelete = profile.MappingStatus[HXStr("删除")].Checked;
if (canRead && !canWrite) {
// 只读模式
}
如果你需要在"某个选项被切换时"触发一次性动作,可以配合上一帧的状态做对比:
static HX::CheckboxGroupProfile profile;
static bool lastRead = false;
HX::CheckboxGroup(HXStr("功能开关"), profile);
bool currentRead = profile.MappingStatus[HXStr("读取")].Checked;
if (currentRead != lastRead) {
// 读取选项发生了切换
lastRead = currentRead;
}
完整示例代码
下面的示例展示了纵向多选组、横向单选组、以及预设默认值的用法。
#include <include/hex.h>
#include <include/impl/EasyX/hex_impl_easyx.h>
int main() {
initgraph(900, 700);
setbkcolor(WHITE);
cleardevice();
HX::HXInitForEasyX();
HX::SetBuffer(GetWorkingImage());
BeginBatchDraw();
// ===== 必须是 static 或全局变量 =====
static HX::WindowProfile wp;
wp.Size = {550, 500};
wp.Position = {175, 100};
// 多选组:兴趣爱好
static HX::CheckboxGroupProfile hobbyProfile;
// 预设选中两个
hobbyProfile.MappingStatus[HXStr("编程")].Checked = true;
hobbyProfile.MappingStatus[HXStr("音乐")].Checked = true;
// 单选组:难度(纵向)
static HX::CheckboxGroupProfile diffProfile;
diffProfile.MappingStatus[HXStr("普通")].Checked = true;
// 单选组:主题(横向)
static HX::CheckboxGroupProfile themeProfile;
themeProfile.MappingStatus[HXStr("暗黑")].Checked = true;
while (true) {
HX::HXBegin();
ExMessage msg;
while (peekmessage(&msg)) {
HX::PushMessage(HX::GetHXMessage(&msg));
}
HX::Window(HXStr("CheckboxGroup 演示"), wp);
// --- 多选组(纵向)---
HX::Text(HXStr("【多选】你的兴趣爱好:"));
HX::CheckboxGroup(HXStr(""), hobbyProfile);
HX::Text(HXStr("已选择:"));
if (hobbyProfile.MappingStatus[HXStr("编程")].Checked)
HX::Text(HXStr(" - 编程"));
if (hobbyProfile.MappingStatus[HXStr("音乐")].Checked)
HX::Text(HXStr(" - 音乐"));
if (hobbyProfile.MappingStatus[HXStr("绘画")].Checked)
HX::Text(HXStr(" - 绘画"));
if (hobbyProfile.MappingStatus[HXStr("运动")].Checked)
HX::Text(HXStr(" - 运动"));
HX::Text(HXStr("")); // 空行
// --- 单选组(纵向)---
HX::Text(HXStr("【单选】游戏难度:"));
HX::CheckboxGroupSingle(HXStr(""), diffProfile);
HX::Text(HXStr("当前难度:"));
if (diffProfile.MappingStatus[HXStr("简单")].Checked)
HX::Text(HXStr(" 简单模式"));
else if (diffProfile.MappingStatus[HXStr("普通")].Checked)
HX::Text(HXStr(" 普通模式"));
else if (diffProfile.MappingStatus[HXStr("困难")].Checked)
HX::Text(HXStr(" 困难模式"));
HX::Text(HXStr("")); // 空行
// --- 单选组(横向)---
HX::Text(HXStr("【单选】界面主题(横向排列):"));
HX::CheckboxGroupSingle(HXStr(""), themeProfile, true);
HX::End();
HX::Render();
FlushBatchDraw();
Sleep(16);
}
closegraph();
return 0;
}
CheckboxGroup 的选项标题是从哪里来的?答案是:框架会根据你第一次调用时传入的 Title 和预设的 MappingStatus 来渲染。如果你发现选项显示不正确,检查一下 MappingStatus 里的键名是否和期望一致。另外,单选组的"互斥"逻辑是由框架在内部保证的,你不需要自己写代码来取消其他选项。
运行效果
截图占位符:请补充 $name 控件的运行效果截图。
截图占位符:请补充
CheckboxGroup 运行效果的运行效果截图,保存为./assets/CheckboxGroup_view.png。`n