Проблема при добавлении компонента GtkVBox в GtkScrolledWindow - PullRequest
1 голос
/ 16 ноября 2009

У меня следующий код / ​​функция, которая добавляет список компонентов в GtkScrolledView.

Сначала он добавляет GtkButton (с GtkLabel + GtkImage в нем) к GtkVBox и GtkVBox к 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 );

}

В этой функции member_name_list_vbox является членом класса, который содержит указатель на GtkVBox, который добавляется в GtkSrolledWindow.

Но проблема в том, что функция вызывается для некоторых внешних событий n раз.

И мне нужно обновить весь список, удалив все виджеты и добавив их снова.

Как я могу это сделать?

Я пытался отменить GtkVBox g_object_unref( G_OBJECT(member_name_list_vbox));, который является моим членом. Но это дает ошибку во время выполнения, когда функция вызывается во второй раз:

(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

И если я не отменю GtkVBox перед созданием нового GtkVBox, я получаю сообщение об ошибке при добавлении GtkVBox в GtkScrolledWindow.
Время выполнения Ошибка при вызове функции во второй раз:

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

Может ли кто-нибудь помочь с этой проблемой?

Ответы [ 2 ]

1 голос
/ 16 ноября 2009

Замените g_object_unref на gtk_widget_destroy, что приведет к отмене поиска и уничтожению виджета GtkVBox, и это сработало для меня!

1 голос
/ 16 ноября 2009

Не случайным образом лишайте ссылки на объект, это вызовет всевозможную путаницу. Удалите vbox из прокручиваемого окна:

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

Это удалит ссылку контейнера на vbox, что должно привести к тому, что его общее число ссылок станет равным 0, уничтожив его. Это уничтожит все дочерние виджеты рекурсивно. После этого вызова ваш указатель на vbox больше не действителен, и поэтому мы можем установить его в NULL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...