使用模板 UI 文件编写自定义 GTK 小部件

问题描述 投票:0回答:1

我正在编写一个自定义小部件,它将使用

AppWindow
作为实用程序窗格显示在
AdwApplicationWindow
(
AdwOverlaySplitView
) 中。

但是,当我将包含

GtkLabel
本身的自定义小部件放置在
AdwOverlaySplitView
的“内容”属性下时,它没有出现。但是,当我使用
GtkLabel
代替时,它显示正确。

这是我的

.ui
.c
文件

  • app-window.ui
?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk" version="4.0"/>
  <requires lib="Adw" version="1.0"/>
  <template class="AppWindow" parent="AdwApplicationWindow">
    <property name="content">
      <object class="AdwToolbarView">
        <child type="top">
          <object class="AdwHeaderBar" id="header_bar">
            <child type="start">
              <object class="GtkToggleButton" id="show_sidebar_button">
                <property name="icon-name">panel-left-symbolic</property>
                <property name="tooltip-text" translatable="yes">Toggle Sidebar</property>
                <property name="active">True</property>
              </object>
            </child>
            <child type="end">
              <object class="GtkMenuButton">
                <property name="primary">True</property>
                <property name="icon-name">open-menu-symbolic</property>
                <property name="tooltip-text" translatable="yes">Menu</property>
                <property name="menu-model">primary_menu</property>
              </object>
            </child>
          </object>
        </child>
        <property name="content">
          <object class="AdwOverlaySplitView" id="split_view">
          <property name="show-sidebar" bind-source="show_sidebar_button" bind-property="active" bind-flags="sync-create|bidirectional"/>
            <property name="sidebar">
                <!-- Sidebar content-->
            </property>
            <property name="content">
                <!-- Main Page content -->
                <object class="MyWidget">                   <!-- This is not getting displayed -->
                </object>
                <object class="GtkLabel">
                  <property name="label">Label</property>   <!-- This is getting displayed -->
              </object>
            </property>
          </object>
        </property>
      </object>
    </property>
  </template>
</interface>
  • my-widget.ui 
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk" version="4.0"/>
  <requires lib="Adw" version="1.0"/>
  <template class="MyWidget" parent="GtkWidget">
    <object class="GtkLabel">
      <property name="label">Label</property>
    </object>
  </template>
</interface>
  • my-widget.c
struct MyWidget
{
  GtkWidget parent_instance;
};


G_DEFINE_TYPE (MyWidget, my_widget, GTK_TYPE_WIDGET)

static void
my_widget_init (MyWidget *self)
{
  gtk_widget_init_template (GTK_WIDGET (self));
}

static void
my_widget_class_init (MyWidgetClass *klass)
{
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

  gtk_widget_class_set_template_from_resource (widget_class, "<resource_path>");
}

我使用了

GTK Inspector
,它能够识别该小部件。然而,从视觉上看,没有任何输出。

尽管我以前使用过

.ui
文件,但它们仍然让我感到困惑。我在这里做错了什么?

gtk desktop gnome gtk4
1个回答
0
投票

如果您想创建基于 GtkWidget 的小部件,您必须手动实现静态方法 Gtk.WidgetClass.get_request_mode,如此处所述。如果没有这个,小部件不会占用空间并且不会被渲染。

虽然在某些情况下实现直接继承自 GtkWidget 的小部件是有意义的,但在大多数情况下,扩展您在自定义小部件中使用的主小部件要简单得多。在您的情况下,GtkLabel,将您的 XML 保留为这样:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
   <requires lib="gtk" version="4.0"/>
   <requires lib="Adw" version="1.0"/>
   <template class="MyWidget" parent="GtkLabel">
      <property name="label">Label</property>
   </template>
</interface>
© www.soinside.com 2019 - 2024. All rights reserved.