使用 C 在 Gtk 中创建小部件列表

Creating a list of widgets in Gtk using C

我想在 Gtk 中创建一个看起来像这样的 window。 widgets in glade

顶部的左窗格 window 有一个标记为“添加到列表”的按钮。我已配置此按钮的回调以将小部件“list_entry”添加到右窗格中的 GtkListBox 中。它是在将小部件的标签从“标签”更改为出现在其正上方的文本条目中的文本之后执行此操作的。 所以,基本上这个按钮将一个新条目添加到位于右窗格中的列表中(可能看起来是空的)。此条目是一个简单的小部件,由一个图标和一个标签(在底部)组成。

现在,我希望“添加到列表”按钮在我每次单击它时创建该条目的新副本,并将该条目附加到右窗格中的列表。但是每次我在列表中添加一个新条目时,它只会覆盖列表的前一个条目并发出警告 -> 正在尝试将 GtkBox 类型的小部件添加到 GtkListBoxRow 类型的容器中,但是该小部件已经在 GtkListBoxRow 类型的容器中,请先从其现有容器中删除该小部件。

我将 GtkListBox 用于右窗格中的列表,并将 GtkBox 用于我应该添加的新条目。

这是“添加到列表”按钮的“点击”回调代码

static void
dw_left_add_btn_cb(CcPrintersPanel * self){
    GtkLabel* row_list_label = (GtkLabel*) gtk_builder_get_object (self->builder, "list_entry_label");

    GtkEntry* text_entry_to_add = (GtkEntry*) gtk_builder_get_object (self->builder, "dw_left_enter_text");

    // debug
    if ( self->list_serv == NULL || row_list_label == NULL) g_debug ("One of object for generating the list did'nt load up in the builder");

    gtk_label_set_label (row_list_label, gtk_entry_get_text (text_entry_to_add));

    gtk_entry_set_text(text_entry_to_add,"");

    GtkWidget* row_list = (GtkWidget*) gtk_builder_get_object (self->builder, "list_entry");

    gtk_list_box_insert (self->list_serv, row_list, -1);
    
}

我想问你如何从使用 .ui 文件加载到 Builder 的小部件创建一个全新的小部件(对于每个新条目)。如果您有其他实现方法,也请告诉我。

GtkBuilder 不是小部件的 工厂。它更像是一个 carton 的小部件。一些伪代码:

GtkWidget *widget1, *widget2;

builder = gtk_builder_new();
widget1 = gtk_builder_get_object(builder, "label");
widget2 = gtk_builder_get_object(builder, "label"); // this will not produce another label but return existing one
// (widget1 == widget2), they point to same object

// let's unpack another carton of widgets...
builder2 = gtk_builder_new(); 
widget2 = gtk_builder_get_object(builder2, "label");
// (widget1 != widget2), now that's really 2 distinct widgets

因此警告。您尝试将小部件添加到 ListBoxRow,但这个确切的小部件已经在 ListBoxRow 中。当您想动态创建 another 小部件时,您必须创建 another GtkBuilder.

static void
dw_left_add_btn_cb(CcPrintersPanel * self){
    GtkBuilder *b = gtk_builder_new();
    GtkLabel* w = (GtkLabel*) gtk_builder_get_object (b, "list_entry_label");

    gtk_list_box_insert (self->list_serv, w, -1);
}