I want to create a window in Gtk that looks something like this. widgets in glade
The left pane in the top window has a button labelled "Add to list". I have configured the callback for this button to add the widget "list_entry" into the GtkListBox in the right pane. It does so after changing the label of the widget from "label" to the text present in a text entry present just above it. So, basically this button add a new entry into a list placed in the right pane(might be seen empty). This entry is a simple widget consisting of an icon and a label( at the bottom).
Now, I want the button "Add to list" to create new copies of this entry every time I click it and append that entry to the list in the right pane. But every time I add a new entry to the list, it simply overwrite the previous entry of the list and gives a warning -> Attempting to add a widget with type GtkBox to a container of type GtkListBoxRow, but the widget is already inside a container of type GtkListBoxRow, please remove the widget from its existing container first.
I am using GtkListBox for the list in the right pane and the GtkBox for the new entry that I am supposed to add.
This is the code for the "click" callback of the button "Add to list"
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);
}
I wanted to ask you how to create an entirely new widget( for every new entry ) from a widget that was loaded into Builder using a .ui file. Please also advise me if you have some other way of implementing this.
GtkBuilder
is not a factory of widgets. It's more like a carton of widgets. Some pseudocode:
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
Hence the warning. You try to add widget to a ListBoxRow, but this exact widget is already in a ListBoxRow. When you want to dynamically create another widget, you must create 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);
}