Chapter 137 · XUI 基础控件

CheckCard 选择卡片

CheckCard 可选中卡片容器,支持角标勾选、RadioGroup 互斥与丰富的状态颜色配置。

137

概念

CheckCard 是可选中卡片,适合选项展示:
• 选中时边框变色 + 角标勾选
• 可加入 RadioGroup 实现卡片单选
• 卡片内可放置任意子控件(图标+文字+描述)
• 支持多选(独立)或单选(Group 模式)

API 速查

函数说明
int xuiCheckCardCreate(xui_context pCtx, xui_widget* ppW, const xui_check_card_desc_t* pDesc)创建选择卡片
int xuiCheckCardSetChange(xui_widget pW, xui_check_card_change_proc onChange, void* pUser)变化回调
int xuiCheckCardSetChecked(xui_widget pW, int bChecked)设置选中
int xuiCheckCardGetChecked(xui_widget pW)获取选中
int xuiCheckCardSetRadioGroup(xui_widget pW, xui_widget pGroup)加入单选组
int xuiCheckCardSetMetrics(xui_widget pW, float fBorder, float fChkBorder, float fCorner, float fFocus)尺寸参数
int xuiCheckCardSetColors(xui_widget pW, ...)9 种颜色
xui_rect_t xuiCheckCardGetCornerRect(xui_widget pW)角标区域

编译本章示例

gcc -O2 -I. -o ch137.exe ch137_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch137.exe

示例:套餐选择卡片

// 创建单选组
xui_widget pGroup;
xuiRadioGroupCreate(pCtx, &pGroup, NULL);

// 创建三张卡片
const char* names[] = { "基础版", "专业版", "企业版" };
for (int i = 0; i < 3; i++) {
    xui_check_card_desc_t desc = { 0 };
    xui_widget pCard;
    xuiCheckCardCreate(pCtx, &pCard, &desc);

    // 卡片内容:标题 + 描述
    xui_widget pTitle;
    xuiLabelCreate(pCtx, &pTitle,
        &(xui_label_desc_t){ .sText = names[i] });
    xuiWidgetAddChild(pCard, pTitle);

    // 加入单选组(互斥)
    xuiRadioGroupAddCheckCard(pGroup, pCard);
    xuiWidgetAddChild(pContainer, pCard);
}

// 默认选中"专业版"
xuiRadioGroupSetSelectedIndex(pGroup, 1);

完整代码

将以下代码保存为 ch137_main.c,编译后运行即可看到卡片单选效果:

#include "xge.h"
#include "xui.h"
#include <stdio.h>

static xui_context g_pCtx;

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    float mx, my;
    xgeMouseGet(&mx, &my);
    xuiInputPointerMove(g_pCtx, mx, my, 0);
    if (xgeMouseDown(XGE_MOUSE_LEFT))
        xuiInputPointerDown(g_pCtx, mx, my, 0, 1);
    if (!xgeMouseDown(XGE_MOUSE_LEFT) /* 释放边沿建议改用事件 */)
        xuiInputPointerUp(g_pCtx, mx, my, 0, 0);
    xuiUpdate(g_pCtx, xgeGetDelta());
    xuiLayout(g_pCtx);
    xuiRender(g_pCtx, NULL, NULL, 0);
    return XGE_OK;
}

int main(void) {
    xge_desc_t d = {0};
    d.iWidth  = 800;
    d.iHeight = 600;
    d.sTitle  = "ch137 - CheckCard";
    d.iFlags  = XGE_INIT_VSYNC;
    xgeInit(&d);

    xuiCreate(&g_pCtx);
    extern const xui_proxy_t tXgeProxy;
    xui_proxy_t tXgeProxy = xuiProxyXge();
xuiSetProxy(g_pCtx, &tXgeProxy);
    xuiSetViewportSize(g_pCtx, 800, 600);

    // 创建单选组 + 三张卡片
    xui_widget pGroup;
    xuiRadioGroupCreate(g_pCtx, &pGroup, NULL);

    const char* names[] = { "Basic", "Pro", "Enterprise" };
    for (int i = 0; i < 3; i++) {
        xui_check_card_desc_t desc = { 0 };
        xui_widget pCard;
        xuiCheckCardCreate(g_pCtx, &pCard, &desc);
        xuiWidgetSetRect(pCard,
            (xui_rect_t){ 100 + i * 220, 200, 180, 120 });
        xuiRadioGroupAddCheckCard(pGroup, pCard);
    }
    xuiRadioGroupSetSelectedIndex(pGroup, 1);

    xgeRun(onFrame, NULL);

    xuiDestroy(g_pCtx);
    xgeUnit();
    return 0;
}

代码讲解

  • xuiCheckCardCreate:创建可选择卡片,可放置任意子控件。
  • xuiRadioGroupAddCheckCard:将卡片加入单选组,实现互斥选择。
  • xuiRadioGroupSetSelectedIndex:默认选中第二张卡片。
  • 多选模式:不加入 Group 时各卡片独立选中/取消。

要点与陷阱

  • RadioGroup:加入 Group 后自动互斥,无需手动管理。
  • CornerRect:右上角勾选标记区域,可自定义大小。
  • 多选模式:不加入 Group 时各卡片独立选中/取消。
  • SetCheckedFromGroup:Group 内部调用,bNotify 控制是否触发回调。

进阶练习

  1. 定价卡片:图标 + 标题 + 价格 + 特性列表。
  2. 多选标签:不加入 Group,实现多选筛选卡片。
CheckCard 选择卡片效果
图:CheckCard 选择卡片渲染效果