You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法重新分配结构体成员值:按钮悬停样式失效排查

按钮悬停样式失效变黑问题分析与解决

问题场景

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 04:35:14