Chapter 167 · XUI 数据录入控件

DatePicker 日期选择

DatePicker 日期/时间选择器,支持日期、时间、日期时间、范围模式,可空值。

167

概念

DatePicker 是日期时间选取控件:
• Mode:Date / Time / DateTime / DateRange
• xtime:引擎时间类型(Unix 时间戳)
• Nullable:允许空值(未选择状态)
• Range:范围模式选择起止时间
• 多回调:Changing / Change / Commit / Cancel / Clear

API 速查

函数说明
int xuiDatePickerCreate(xui_context pCtx, xui_widget* ppW, const xui_date_picker_desc_t* pDesc)创建日期选择器
int xuiDatePickerSetMode(xui_widget pW, int iMode)模式
int xuiDatePickerSetValue(xui_widget pW, xtime tValue)设置值
int xuiDatePickerSetRangeValue(xui_widget pW, xtime tStart, xtime tEnd)范围值
int xuiDatePickerGetRangeValue(xui_widget pW, xtime* pStart, xtime* pEnd)获取范围
int xuiDatePickerSetNullable(xui_widget pW, int bNullable)允许空值
int xuiDatePickerHasValue(xui_widget pW)是否有值
int xuiDatePickerClearValue(xui_widget pW)清除
int xuiDatePickerSetChange(xui_widget pW, xui_date_picker_proc onChange, void* pUser)确认回调
int xuiDatePickerSetChanging(xui_widget pW, xui_date_picker_proc onChanging, void* pUser)实时回调

编译本章示例

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

示例:预约时间选择

xui_date_picker_desc_t desc = { 0 };

xui_widget pDate;
xuiDatePickerCreate(pCtx, &pDate, &desc);

// 日期+时间模式
xuiDatePickerSetMode(pDate, 2);  // DateTime
xuiDatePickerSetNullable(pDate, 1);

// 设置默认值为当前时间
xuiDatePickerSetValue(pDate, xgeTimeNow());

// 确认选择回调
xuiDatePickerSetChange(pDate, OnDateChange, NULL);

static void OnDateChange(xui_widget pW, xtime tValue, void* pUser) {
    ScheduleAppointment(tValue);
}

// 范围模式
xuiDatePickerSetMode(pDate, 3);  // DateRange
xuiDatePickerSetRangeValue(pDate, tStart, tEnd);

完整代码

将以下代码保存为 ch167_main.c,编译后运行即可看到 DatePicker 日期选择效果:

#include "xge.h"
#include "xui.h"

static xui_context g_pCtx;

static void OnDateChange(xui_widget pW, xtime tValue, void* pUser) {
    (void)pW; (void)pUser;
    xgeLogWrite("选中时间: %lld", (long long)tValue);
}

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    xui_vec2_t pos; xgeMouseGet(&pos.x, &pos.y);
    xuiInputPointerMove(g_pCtx, pos.x, pos.y);
    if (xgeMouseDown(XGE_MOUSE_LEFT)) xuiInputPointerDown(g_pCtx, pos.x, pos.y, 0);
    else xuiInputPointerUp(g_pCtx, pos.x, pos.y, 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 = "ch167 - DatePicker";
    d.iFlags = XGE_INIT_VSYNC;
    xgeInit(&d);
    xuiCreate(&g_pCtx);
    /* XGE 官方代理由 xuiProxyXge() 提供 */
    xui_proxy_t tXgeProxy = xuiProxyXge();
xuiSetProxy(g_pCtx, &tXgeProxy);
    xuiSetViewportSize(g_pCtx, 800, 600);

    xui_widget pRoot;
    xuiPanelCreate(g_pCtx, &pRoot, NULL);
    xuiWidgetSetRect(pRoot, (xui_rect_t){0, 0, 800, 600});

    /* 日期选择器 */
    xui_date_picker_desc_t dpDesc = {0};
    xui_widget pDate;
    xuiDatePickerCreate(g_pCtx, &pDate, &dpDesc);
    xuiWidgetSetRect(pDate, (xui_rect_t){0, 0, 220, 32});
    xuiWidgetSetRect(pDate, (xui_rect_t){290, 200, 220, 32});
    xuiDatePickerSetMode(pDate, 2); /* DateTime */
    xuiDatePickerSetNullable(pDate, 1);
    xuiDatePickerSetValue(pDate, xgeTimeNow());
    xuiDatePickerSetChange(pDate, OnDateChange, NULL);
    xuiWidgetAddChild(pRoot, pDate);

    xgeRun(onFrame, NULL);
    xuiDestroy(g_pCtx);
    xgeUnit();
    return 0;
}

代码讲解

  • xuiDatePickerCreate:创建日期选择器控件。
  • SetMode(2):DateTime 模式,同时选择日期和时间。
  • SetNullable(1):允许空值,显示清除按钮。
  • SetValue(xgeTimeNow()):默认值为当前系统时间。
  • OnChange:用户确认选择后触发回调。

要点与陷阱

  • Mode:0=Date, 1=Time, 2=DateTime, 3=DateRange。
  • Changing vs Change:Changing 在面板操作时实时触发,Change 在确认时触发。
  • Nullable:启用后显示清除按钮,ClearValue 后 HasValue 返回 0。
  • xtime:64 位时间戳,使用 xgeTimeNow() 获取当前时间。

进阶练习

  1. 日期范围筛选:报表起止日期选择 + 快捷选项(本周/本月)。
  2. 禁用日期:配合 Changing 回调阻止选择周末。
DatePicker 日期选择效果
图:DatePicker 日期选择渲染效果