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
相关产品推荐
相关产品推荐

