我有以下代码/功能,它将组件列表添加到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中。
但问题是该函数多次在某些外部事件上被调用。
我需要通过删除所有小部件并再次添加它们来刷新整个列表。
我该怎么做?
我尝试取消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,我在GtkScrolledWindow中添加GtkVBox时会出现错误。
运行时第二次调用函数时出错:
(App:8618): Gtk-CRITICAL **: gtk_scrolled_window_add_with_viewport: assertion `GTK_BIN (bin->child)->child == NULL' failed
有人能为这个问题提供一些帮助吗?
答案 0 :(得分:1)
不要随意取消引用对象,这会引起各种混淆。从滚动窗口中删除vbox:
gtk_container_remove(GTK_CONTAINER(scrolled_window), member_name_list_vbox);
member_name_list_vbox = NULL;
这将删除容器对vbox的引用,这将导致其总引用计数变为0,从而销毁它。这将以递归方式销毁所有子窗口小部件。在此调用之后,指向vbox的指针不再有效,因此我们可以将其设置为NULL。
答案 1 :(得分:1)
将g_object_unref
替换为gtk_widget_destroy
,这将取消并破坏GtkVBox小部件,它确实对我有效!