无法重新分配结构体成员值:按钮悬停样式失效排查
按钮悬停样式失效变黑问题分析与解决
问题场景
在main.c中为按钮结构体设置样式:
struct SCGUI_Button button = scgui_new_button(); button.style = (SCGUI_ButtonStyle) { .background_color = new_color(255, 0, 0), .hover = { .font_family = "res/Cursive.ttf", .background_color = new_color(255, 0, 0) // 此处定义hover背景色 } }; // 更新函数(用于悬停) scgui_draw_button(&button, CENTER);
在button.c中实现按钮初始化和绘制函数:
struct SCGUI_Button scgui_new_button() { // 默认初始化值 struct SCGUI_Button button = { .style = { .background_color = new_color(200, 200, 200), .font_color = new_color(0, 0, 0), .font_family = "res/Roboto.ttf", .font_size = 24, .hover = { .background_color = new_color(220, 220, 220), .font_color = new_color(20, 20, 20), .font_family = "res/Roboto.ttf", .font_size = 24 } } }; return button; } void scgui_draw_button(struct SCGUI_Button *self) { if (button_hovered(self->area, app.mouse_pos.x, app.mouse_pos.y)) { self->state.hovered = true; // 尝试将实际按钮样式设置为悬停样式(使用main.c中提供的值,若无则使用初始化默认值) self->style = (SCGUI_ButtonStyle) { .background_color = self->style.hover.background_color, .font_color = self->style.hover.font_color, .font_family = self->style.hover.font_family == NULL ? "res/Roboto.ttf" : self->style.hover.font_family, .font_size = self->style.hover.font_size == 0 ? 24 : self->style.hover.font_size, }; } }
问题现象
悬停功能生效,但按钮直接变黑,自定义的样式设置无效。
错误原因及解决方法
1. main.c中结构体整体赋值覆盖默认成员
你在main.c中用button.style = (SCGUI_ButtonStyle) { ... }整体替换样式结构体,这会把所有未显式指定的成员重置为默认值(通常是0)。比如:
button.style.font_color被重置为RGB(0,0,0)button.style.hover.font_color、button.style.hover.font_size也会被重置为0,而非保留scgui_new_button()中的默认值
解决方法:不要整体替换style,逐个修改需要自定义的成员:
struct SCGUI_Button button = scgui_new_button(); // 仅修改需要自定义的属性,保留其他默认值 button.style.background_color = new_color(255, 0, 0); button.style.hover.font_family = "res/Cursive.ttf"; button.style.hover.background_color = new_color(255, 0, 0);
2. scgui_draw_button中错误覆盖原样式结构体
在绘制函数里,你直接把self->style替换成新结构体,会丢失原本的非悬停样式。而且当self->style.hover.font_color是0(main.c赋值导致),直接赋值给self->style.font_color就会出现黑色。
正确逻辑:不需要替换整个style,绘制时根据悬停状态选择对应样式属性即可:
void scgui_draw_button(struct SCGUI_Button *self) { // 默认使用基础样式 SCGUI_ButtonStyle *draw_style = &self->style; if (button_hovered(self->area, app.mouse_pos.x, app.mouse_pos.y)) { self->state.hovered = true; // 悬停时使用hover样式 draw_style = &self->style.hover; } else { self->state.hovered = false; } // 绘制时直接使用draw_style的属性 // 示例: // draw_button_background(draw_style->background_color); // draw_button_text(draw_style->font_color, draw_style->font_family, draw_style->font_size); }
如果一定要修改self->style适配状态,建议在结构体中保存原始默认样式,非悬停时恢复:
// 先修改SCGUI_Button结构体,添加默认样式成员 typedef struct SCGUI_Button { SCGUI_ButtonStyle style; SCGUI_ButtonStyle default_style; // 保存初始默认样式 // 其他成员... } SCGUI_Button; // 初始化时复制默认样式 struct SCGUI_Button scgui_new_button() { struct SCGUI_Button button = { .style = { /* ...默认样式... */ }, }; button.default_style = button.style; return button; } void scgui_draw_button(struct SCGUI_Button *self) { if (button_hovered(self->area, app.mouse_pos.x, app.mouse_pos.y)) { self->state.hovered = true; // 基于默认样式,合并hover自定义属性 self->style = self->default_style; self->style.background_color = self->style.hover.background_color; self->style.font_family = self->style.hover.font_family; // 按需处理其他属性 } else { self->state.hovered = false; self->style = self->default_style; // 恢复默认样式 } }
内容的提问来源于stack exchange,提问作者Scollier
相关产品推荐
相关产品推荐

