使用 C

问题描述

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

顶部窗口的左窗格有一个标记为“添加到列表”的按钮。我已经为这个按钮配置了回调,以将小部件“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 不是小部件的工厂。它更像是一个纸箱的小部件。一些伪代码:

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 中。当您想动态创建另一个小部件时,您必须创建另一个 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);
}