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

GTK4代码加载Glade生成的builder.ui异常,窗口无控件显示

GTK4加载Glade生成的UI文件后窗口内控件不显示

按照GTK4官方文档的示例代码,使用gtk_builder_add_from_file()加载Glade生成的builder.ui文件,编译运行后窗口标题与Glade中定义的一致,但窗口内的按钮控件完全不显示。程序编译运行无报错。

问题相关代码

builder.ui 文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
  <requires lib="gtk+" version="3.24"/>
  <object class="GtkWindow" id="MainWindow">
    <property name="can-focus">False</property>
    <property name="title" translatable="yes">MyApp</property>
    <property name="default-width">440</property>
    <property name="default-height">250</property>
    <signal name="destroy" handler="exit_app" swapped="no"/>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <placeholder/>
        </child>
        <child>
          <object class="GtkButton" id="Button">
            <property name="label" translatable="yes">button</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

C 代码文件

#include <gtk/gtk.h>
#include <glib/gstdio.h>

static void print_hello(GtkWindow * window, gpointer data)
{
    g_print("Clicked");
}

// renders the application
static void activate(GtkApplication * app, gpointer * user_data)
{
    /* Construct a GtkBuilder instance and load our UI description */
    GtkBuilder *builder = gtk_builder_new ();
    gtk_builder_add_from_file (builder, "builder.ui", NULL);

    // connect signal handlers to the constructed widgets
    GObject * window = gtk_builder_get_object(builder,"MainWindow");
    gtk_window_set_application(GTK_WINDOW(window), app);

    gtk_widget_show(GTK_WIDGET(window));

    // unload the builder (destroy)
    g_object_unref(builder);

}


int main(int argc, char ** argv)
{

    #ifdef GTK_SCRDIR
        g_chdir(GTK_SCRDIR);
    #endif

    GtkApplication * app = gtk_application_new("org.gtk.application", G_APPLICATION_FLAGS_NONE);
    g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);

    int status = g_application_run(G_APPLICATION(app), argc, argv);

    g_object_unref(app);

    return status;
}

问题原因及修复步骤

  1. UI文件GTK版本不匹配
    Glade生成的UI文件依赖GTK3(<requires lib="gtk+" version="3.24"/>),但程序使用的是GTK4,两者控件结构存在兼容性差异。需修改UI文件的依赖声明:
    将<requires lib="gtk+" version="3.24"/>替换为:

    <requires lib="gtk4" version="4.0"/>
    

    建议创建Glade项目时直接选择GTK4模板,避免生成GTK3结构的UI文件。

  2. GTK4显示逻辑变更
    GTK4中gtk_widget_show()仅显示目标控件本身,不会递归显示其子控件。当前代码仅调用该函数显示窗口,导致内部的Box和Button未被渲染。需替换为递归显示函数:
    将代码中的:

    gtk_widget_show(GTK_WIDGET(window));
    

    修改为:

    gtk_widget_show_all(GTK_WIDGET(window));
    
  3. 移除未实现的信号绑定(可选)
    UI文件中绑定了destroy信号到exit_app函数,但代码未实现该函数,运行时会产生警告。可删除UI文件中的该信号绑定,或在代码中添加实现:

    static void exit_app(GtkWindow *window, gpointer data)
    {
        g_application_quit(G_APPLICATION(gtk_window_get_application(window)));
    }
    

修改后重新编译运行,窗口内的按钮控件即可正常显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 07:55:25