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

GTK3按钮连接gtk_main_quit触发GObject断言错误求助

问题分析与修复方案

核心问题:控件指针未正确初始化

报错的直接原因是modelo_estrutura_erro->botao_erro为NULL,导致g_signal_connect触发G_TYPE_CHECK_INSTANCE断言失败。问题出在criar_widget的调用方式上:你当前直接传递结构体成员(如modelo_estrutura_erro->janela_erro)属于传值调用,函数内部无法修改结构体里的指针变量,所以这些控件指针始终保持空值。

修复步骤

1. 修正criar_widget的调用方式

假设criar_widget的作用是从GtkBuilder中获取控件并赋值给传入的指针,需要传递结构体成员的地址:

criar_widget(&modelo_estrutura_erro->janela_erro, construtor,"janela_erro");
criar_widget(&modelo_estrutura_erro->box_erro, construtor,"box_erro");
criar_widget(&modelo_estrutura_erro->botao_erro, construtor,"botao_erro");

同时确保criar_widget的函数定义接收GtkWidget**类型参数,示例实现:

void criar_widget(GtkWidget **widget, GtkBuilder *builder, const gchar *name) {
    *widget = GTK_WIDGET(gtk_builder_get_object(builder, name));
}

2. 移除多余的malloc调用

代码开头的construtor = malloc(sizeof construtor);完全多余,后续gtk_builder_new_from_file会返回新的GtkBuilder实例覆盖该指针,还会造成内存泄漏,直接删除这行代码。

3. 增加控件指针有效性检查

在调用g_signal_connect前,验证按钮指针是否有效,避免空指针触发错误:

if (!modelo_estrutura_erro->botao_erro) {
    g_printerr("Botão de erro não encontrado no arquivo glade\n");
    g_object_unref(construtor);
    return FALSE;
}

修复后的完整代码片段

int mensagem_erro()
{
    GtkBuilder *construtor = NULL;

    printf("Alocando a janela...\n");
    alojar_erro();

    printf("Gerando a mensagem de erro...\n");
    snprintf(modelo_estrutura_erro->string_erro, TAMANHO_STRING_ERRO-1,"Erro! Erro n %i, do tipo: %s", errno, strerror(errno));

    printf("Criando a tela de erro...\n");
    construtor = gtk_builder_new_from_file("tela_erro.glade");

    if(construtor==NULL)
    {
        printf("Erro! Erro n %i, do tipo: %s", errno, strerror(errno));
        return FALSE;
    }

    printf("Alocando os dados da tela de erro...\n");
    modelo_estrutura_erro->label_erro = GTK_LABEL(gtk_builder_get_object(construtor, "label_erro"));

    if(modelo_estrutura_erro->label_erro==NULL){
        printf("Erro ao alocar a estrutura!\n");
        return FALSE;
    }

    // 传递指针地址给criar_widget
    criar_widget(&modelo_estrutura_erro->janela_erro, construtor,"janela_erro");
    criar_widget(&modelo_estrutura_erro->box_erro, construtor,"box_erro");
    criar_widget(&modelo_estrutura_erro->botao_erro, construtor,"botao_erro");

    // 检查按钮指针是否有效
    if (!modelo_estrutura_erro->botao_erro) {
        g_printerr("Falha ao recuperar botão de erro\n");
        g_object_unref(construtor);
        return FALSE;
    }

    printf("Inicializando os sinais da tela de erro...\n");
    g_signal_connect(GTK_WIDGET(modelo_estrutura_erro->botao_erro), "clicked", G_CALLBACK(gtk_main_quit), NULL);

    printf("Alocando a mensagem na tela de erro...\n");
    gtk_label_set_text(modelo_estrutura_erro->label_erro, modelo_estrutura_erro->string_erro);

    printf("Mostrando a janela de erro...\n");
    gtk_widget_show(modelo_estrutura_erro->janela_erro);

    g_object_unref(construtor);
    return TRUE;
}

额外注意事项

  • 确保alojar_erro()正确初始化了modelo_estrutura_erro的所有成员(包括string_erro的内存分配)
  • 检查"tela_erro.glade"文件中,控件ID(janela_erro、botao_erro等)与代码中的名称完全一致(大小写敏感)

内容的提问来源于stack exchange,提问作者gustavo moretto itikawa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:53:19