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

GTK4+Glade模态表单输入验证:输入值获取为空问题求助

GTK4模态表单获取输入值为空的问题解决

1. 变量为空的原因

你在on_button_confirm_clicked回调中重新调用了gtk_builder_new_from_file("design.glade"),这会创建一个全新的UI控件树,和用户正在输入的那个模态窗口完全是两个独立的对象。你获取的输入框是这个新树里的空实例,自然读不到用户之前输入的内容。

2. 正确获取并验证输入值的方法

有两种可靠的方式解决这个问题:

方法一:从模态窗口直接查找子控件

利用GTK4的gtk_widget_find_child()函数,直接从已显示的模态窗口中查找输入框控件,无需重新加载Glade文件:

void on_button_confirm_clicked(GtkButton *button, gpointer user_data)
{
    GtkWidget *modal_window = GTK_WIDGET(user_data);
    
    // 从模态窗口中查找指定名字的输入控件
    GtkWidget *first_name_entry = gtk_widget_find_child(modal_window, "first_name_entry");
    GtkWidget *second_name_entry = gtk_widget_find_child(modal_window, "second_name_entry");
    GtkWidget *id_entry = gtk_widget_find_child(modal_window, "id_entry");

    // 检查控件是否找到
    if (!first_name_entry || !second_name_entry || !id_entry) {
        g_warning("无法找到输入控件");
        return;
    }

    const char *first_name = gtk_editable_get_text(GTK_EDITABLE(first_name_entry));
    const char *second_name = gtk_editable_get_text(GTK_EDITABLE(second_name_entry));
    const char *id_text = gtk_editable_get_text(GTK_EDITABLE(id_entry));

    // 验证逻辑
    if (strlen(first_name) == 0)
    {
        printf("输入为空 ");
    }
    else
    {
        printf("名字:%s\n", first_name);
    }

    // 关闭模态窗口
    gtk_window_close(GTK_WINDOW(modal_window));
}

方法二:传递真实控件的引用给回调

在创建模态窗口时,将输入框的引用打包成结构体,作为user_data传递给确认按钮的回调,确保操作的是用户交互的真实控件:

首先定义存储控件引用的结构体:

typedef struct {
    GtkWidget *first_name_entry;
    GtkWidget *second_name_entry;
    GtkWidget *id_entry;
    GtkWidget *modal_window;
} ModalData;

修改添加按钮的回调:

void on_button_add_clicked(GtkButton *button, gpointer user_data)
{
    printf("添加按钮被点击\n");

    GtkBuilder *builder = gtk_builder_new_from_file("design.glade");
    GtkWidget *modal_window = GTK_WIDGET(gtk_builder_get_object(builder, "add_item_modal"));
    GtkWidget *confirm_button = GTK_WIDGET(gtk_builder_get_object(builder, "button_confirm"));

    // 分配结构体并存储控件引用
    ModalData *data = g_new(ModalData, 1);
    data->first_name_entry = GTK_WIDGET(gtk_builder_get_object(builder, "first_name_entry"));
    data->second_name_entry = GTK_WIDGET(gtk_builder_get_object(builder, "second_name_entry"));
    data->id_entry = GTK_WIDGET(gtk_builder_get_object(builder, "id_entry"));
    data->modal_window = modal_window;

    // 增加控件引用计数,防止提前销毁
    g_object_ref(data->first_name_entry);
    g_object_ref(data->second_name_entry);
    g_object_ref(data->id_entry);
    g_object_ref(data->modal_window);

    // 设置模态窗口的父窗口
    GtkWindow *parent_window = GTK_WINDOW(user_data);
    gtk_window_set_transient_for(GTK_WINDOW(modal_window), parent_window);

    // 连接确认按钮信号,传递结构体
    g_signal_connect(confirm_button, "clicked", G_CALLBACK(on_button_confirm_clicked), data);
    // 连接窗口关闭信号,释放资源
    g_signal_connect(modal_window, "close-request", G_CALLBACK(on_modal_closed), data);

    gtk_window_present(GTK_WINDOW(modal_window));

    g_object_unref(builder);
}

添加窗口关闭的回调用于释放资源:

void on_modal_closed(GtkWindow *window, gpointer user_data)
{
    ModalData *data = (ModalData*)user_data;
    // 释放控件引用
    g_object_unref(data->first_name_entry);
    g_object_unref(data->second_name_entry);
    g_object_unref(data->id_entry);
    g_object_unref(data->modal_window);
    // 释放结构体内存
    g_free(data);
}

最后修改确认按钮的回调:

void on_button_confirm_clicked(GtkButton *button, gpointer user_data)
{
    ModalData *data = (ModalData*)user_data;

    const char *first_name = gtk_editable_get_text(GTK_EDITABLE(data->first_name_entry));
    const char *second_name = gtk_editable_get_text(GTK_EDITABLE(data->second_name_entry));
    const char *id_text = gtk_editable_get_text(GTK_EDITABLE(data->id_entry));

    // 验证逻辑
    if (strlen(first_name) == 0)
    {
        printf("输入为空 ");
    }
    else
    {
        printf("名字:%s\n", first_name);
    }

    // 关闭模态窗口
    gtk_window_close(GTK_WINDOW(data->modal_window));
}

注意事项

  • 不要在回调中重复加载Glade文件,这会创建新的控件实例,无法获取用户输入。
  • 处理GTK对象的引用计数,避免内存泄漏或控件提前销毁。

内容的提问来源于stack exchange,提问作者Oussama

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:14:50