【问题标题】:Make known subclassed wigets in .ui files in GTK+在 GTK+ 的 .gui 文件中制作已知的子类小部件
【发布时间】:2021-12-30 17:19:34
【问题描述】:

我正在查看 GNOME 日历应用程序,gcal-window.ui 文件中有这一行(在 292 上):

<object class="GcalQuickAddPopover" id="quick_add_popover">

gcal-window ui、源代码和头文件所在的同一目录中,有定义GcalQuickAddPopover 的文件。使.ui 文件知道哪些对象存在,哪些不存在的规则是什么。如果我删除了 gcal-quick-add-popover 文件,它怎么知道或不知道它在那里?

【问题讨论】:

    标签: widget gtk subclass glade


    【解决方案1】:

    可以在GtkBuilder UI definition 中使用的类型是在解析 XML 之前在运行时注册的类型(通常通过调用 gtk_builder_new 或类似方法)。

    这里有一个独立的例子来说明这一点。

    /* cc ui.c -o ui $(pkg-config --cflags --libs gtk+-3.0) */
    
    #include <gtk/gtk.h>
    
    
    /* Define new type (MyCustomLabel) */
    
    #define MY_TYPE_CUSTOM_LABEL my_custom_label_get_type()
    struct _MyCustomLabel { GtkLabel label; };
    
    G_DECLARE_FINAL_TYPE(MyCustomLabel, my_custom_label, MY, CUSTOM_LABEL, GtkLabel)
    G_DEFINE_TYPE(MyCustomLabel, my_custom_label, GTK_TYPE_LABEL)
    
    static void
    my_custom_label_class_init(MyCustomLabelClass *cls)
    {
    }
    
    static void
    my_custom_label_init(MyCustomLabel *label)
    {
        gtk_label_set_label(GTK_LABEL(label), "This is my custom label");
    }
    
    
    /* Test case */
    
    static const gchar *ui =
        "<interface>"
            "<object id='W' class='GtkWindow'>"
                "<child>"
                    "<object class='MyCustomLabel'/>"
                "</child>"
            "</object>"
        "</interface>";
    
    
    int main()
    {
        GtkBuilder *builder;
        GtkWidget *window;
    
        gtk_init(NULL, NULL);
    
        /* Ensures that MyCustomLabel has been registered with the type
         * system. Without this call, the application crashes when parsing
         * `ui`, i.e. at the `gtk_builder_new_from_string` call. */
        g_type_ensure(MY_TYPE_CUSTOM_LABEL);
    
        builder = gtk_builder_new_from_string(ui, -1);
        window = GTK_WIDGET(gtk_builder_get_object(builder, "W"));
        g_object_unref(builder);
    
        gtk_widget_show_all(window);
        gtk_main();
    
        return 0;
    }
    

    有关类型系统如何工作的更多详细信息,请参阅GObject documentation

    【讨论】:

      【解决方案2】:

      原答案

      这是通过使用构建系统来实现的。通常在 Gnome 中,这是 Meson Build System(之前是 Autotools)。

      作为一个非常简单的解释,该工具在运行时会查看各种meson.build 文件(例如,this one 用于视图)并构建一个 Makefile 来构建项目.在这些文件中,描述了文件和资源之间的依赖关系。实际上,介子的意义远不止于此,我鼓励您阅读它。

      这是位于gui 目录下的meson.build 文件:

      subdir('calendar-management')
      subdir('event-editor')
      subdir('gtk')
      subdir('icons')
      subdir('importer')
      subdir('views')
      
      calendar_incs +=  include_directories('.')
      
      built_sources += gnome.compile_resources(
        'gui-resources',
        'gui.gresource.xml',
        c_name: 'gui',
      )
      
      sources += files(
        'gcal-application.c',
        'gcal-calendar-popover.c',
        'gcal-event-popover.c',
        'gcal-event-widget.c',
        'gcal-expandable-entry.c',
        'gcal-meeting-row.c',
        'gcal-quick-add-popover.c',
        'gcal-search-button.c',
        'gcal-weather-settings.c',
        'gcal-window.c',
      )
      

      您可以在第 6 行看到包含子目录 views。这是gcal-window.ui 了解其观点的地方。

      跟进

      如果您要删除 quick_add_popover.ui 文件,当您尝试使用您的实际 Makefile 进行构建时,构建将失败,因为 Makefile 中的某个位置 Meson 会为您编写,该资源(在本例中为 quick_add_popover.ui)将被引用,但在你的代码中它会消失。

      其他有趣的文件:

      1. gui.gresource.xmlgui 下。这是定义 ui 文件资源的地方。
      2. meson.buildgui 下的文件。这是通过gnome.compile_resources 函数将gui.gressource.xml 告知Meson 的地方。

      我建议您阅读有关 Meson 的信息或在 YouTube 上查看以了解更多信息。

      【讨论】:

      • 嗨,@BobMorane,我缩小了我的问题范围,你能否提供一些细节。很好的答案,顺便说一句!
      • 我添加了一些内容。
      • 这提供了一个关于如何实现典型 GTK probject 的广泛视图,但它没有回答这个问题。可以在GtkBuilder 定义文件中使用特定类型这一事实与构建系统没有任何关系。
      • 尽管您的回答很好并且解释了代码级别发生的情况,但我不同意我的回答“没有回答问题”。 OP 写道:“如果我删除了 gcal-quick-add-popover 文件,它怎么会知道或不知道它的存在?”。对我来说,一个与项目相关的答案可以回答这个问题,但只是在另一个层面上。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      相关资源
      最近更新 更多