tags:

views:

192

answers:

2

I am having following code/function which adds list of components to the GtkScrolledView.

It first adds GtkButton (with GtkLabel+GtkImage in it) to GtkVBox and GtkVBox to GtkScrolledWindow:

void displayTestNameList()
{
    // Get Scrolled Window from Builder.  
    GtkWidget *scrolled_window = GTK_WIDGET( gtk_builder_get_object( myBuilder, "scrolled_window_name_list"));
    GtkWidget *vBox, *image, *button, *hbox, *label;

    // Delete Old List   --> Error On This Line
    if( member_name_list_vbox )
         g_object_unref( G_OBJECT(member_name_list_vbox));

    //Create new GtkVBox to display name list
    member_name_list_vbox = gtk_vbox_new(FALSE, 0);

    for(int loopIndex = 0; loopIndex < member_list.size(); loopIndex++)
    {
        button = gtk_button_new();

        gtk_button_set_relief( GTK_BUTTON( button ), GTK_RELIEF_NONE );
        gtk_button_set_focus_on_click( GTK_BUTTON( button ), FALSE );
        gtk_button_set_alignment( GTK_BUTTON( button ), 0, 1 );

        // Attache call back signal.
        g_signal_connect(button, "event", G_CALLBACK(cb_user_options), NULL);

        // Set Presence Status icon
        hbox = gtk_hbox_new(FALSE, 0);
        gtk_container_add(GTK_CONTAINER(button), hbox);
        image = gtk_image_new_from_file("icon.png");

        // Create Label
        label = gtk_label_new(NULL);
        gtk_label_set_justify( GTK_LABEL(label), GTK_JUSTIFY_LEFT );
        gtk_misc_set_alignment( GTK_MISC(label), 0, 1 );
        gtk_misc_set_padding( GTK_MISC(label), 10, 2 );
        markup = g_markup_printf_escaped ("<span foreground='#151B54'><b>%s</b></span>", (const char*)(member_list[loopIndex].name) );
        gtk_label_set_markup( GTK_LABEL(label), markup );
        g_free (markup);

        // Create Custom Composite GtkButton Widget (GtkImage+GtkLabel)
        gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, TRUE, 0);
        gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);

        // Add this to Class Member GtkVBox 
        gtk_box_pack_start( GTK_BOX(member_name_list_vbox), button, FALSE, FALSE, 0);
    }

    // Add GtkVBox To GtkScrollWindow
    gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
                                           member_name_list_vbox );

    //Show Scrolled Window
    gtk_widget_show_all( scrolled_window );

}

In this function member_name_list_vbox is a class member which holds pointer to GtkVBox which is getting added in GtkSrolledWindow.

But problem is that the function gets called on some external event(s) n number of times.

And I need to refresh whole list by removing all the widgets and adding them again.

How can I do this?

I tried to unref GtkVBox g_object_unref( G_OBJECT(member_name_list_vbox)); which is my member. But it is giving run-time error when function gets called 2nd time:

(App:7614): GLib-GObject-WARNING **: instance of invalid non-instantiatable type `(null)'
(App:7614): GLib-GObject-CRITICAL **: g_signal_emit_valist: assertion `G_TYPE_CHECK_INSTANCE (instance)' failed
(App:7614): GLib-GObject-WARNING **: instance of invalid non-instantiatable type `(null)'
(App:7614): GLib-GObject-CRITICAL **: g_signal_handlers_destroy: assertion `G_TYPE_CHECK_INSTANCE (instance)' failed

And if I don't unref GtkVBox before creating new GtkVBox, I get Error While Adding GtkVBox to GtkScrolledWindow.
Run time Error when function gets called 2nd time:

(App:8618): Gtk-CRITICAL **: gtk_scrolled_window_add_with_viewport: assertion `GTK_BIN (bin->child)->child == NULL' failed

Can some one provide some help with this issue?

A: 

Don't randomly de-reference the object, that will cause all kinds of confusion. Remove the vbox from the scrolled window:

gtk_container_remove(GTK_CONTAINER(scrolled_window), member_name_list_vbox);
member_name_list_vbox = NULL;

This will remove the container's reference to the vbox, which should cause its total reference count to become 0, thus destroying it. This will destroy all the child widgets recursively. After this call, your pointer to the vbox is no longer valid, and thus we can set it to NULL.

unwind
Added gtk_container_remove before creating new vBox.And getting this error: (App:8957): Gtk-CRITICAL **: gtk_container_remove: assertion `GTK_IS_TOOLBAR (container) || widget->parent == GTK_WIDGET (container)' failed
PP
Huh? That looks as if GTK+ considers your container (the vbox) to have itself as a parent. That shouldn't be possible. I don't have the GTK+ source code handy, normally in cases where I get an unexpected error from within GTK+ I read the code. I think something else is wrong here, I would really expect it to work if you remove the vbox from the scrolled window. Strange.
unwind
But it is not working as we expect :(
PP
A: 

Replace g_object_unref with gtk_widget_destroy which will unref and destroy GtkVBox widget, and it does worked for me!

PP