多次重用gtk_file_chooser_dialog

时间:2016-05-16 11:46:24

标签: gtk3

我想多次重复使用gtk_file_chooser_dialog。但是在用户第一次关闭对话框后,指向GtkFileChooserDialog结构的指针似乎被破坏了。

第一次成功打开diaglog。 再次打开同一个对话框会产生

(crystal_facet_uml:3797): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkWidget'
(crystal_facet_uml:3797): Gtk-CRITICAL **: gtk_widget_show_all: assertion 'GTK_IS_WIDGET (widget)' failed

我的第一个想法是增加对话框上的引用计数器,以防止它被清除:

(*this_).use_db_file_chooser = gtk_file_chooser_dialog_new ( "Select DB to use",
                                                             GTK_WINDOW( (*this_).window ),
                                                             GTK_FILE_CHOOSER_ACTION_SAVE,
                                                             "Cancel",
                                                             GTK_RESPONSE_CANCEL,
                                                             "Create/Use DB-File",
                                                             GTK_RESPONSE_ACCEPT,
                                                             NULL
                                                           );
g_object_ref( (*this_).use_db_file_chooser );

...但这只会改变问题:对话窗口似乎停留,但所包含的小部件已经消失:

(crystal_facet_uml:3797): Gtk-CRITICAL **: gtk_container_foreach: assertion 'GTK_IS_CONTAINER (container)' failed
(crystal_facet_uml:3797): Gtk-CRITICAL **: gtk_container_foreach: assertion 'GTK_IS_CONTAINER (container)' failed
(crystal_facet_uml:3797): Gtk-CRITICAL **: gtk_container_foreach: assertion 'GTK_IS_CONTAINER (container)' failed
(crystal_facet_uml:3797): Gtk-CRITICAL **: gtk_container_foreach: assertion 'GTK_IS_CONTAINER (container)' failed
(crystal_facet_uml:3797): Gtk-CRITICAL **: _gtk_file_chooser_embed_initial_focus: assertion 'GTK_IS_FILE_CHOOSER_EMBED (chooser_embed)' failed
Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
(crystal_facet_uml:3797): Gtk-CRITICAL **: gtk_container_foreach: assertion 'GTK_IS_CONTAINER (container)' failed

你知道如何做到这一点吗?

(重新使用文件选择器对话框的基本原理是:1)我想在开始时分配它,之后不再关心NULL指针,2)我想保留对话框的内容(当前文件夹,当前文件名),3)我想只启动一次非模态对话框,而不是同时启动2个对话框,4)我想在程序的整个生命周期内保留g_signal绑定。)

(完整源代码:https://sourceforge.net/p/crystal-facet-uml/code/ci/46ee183ea06baae3af70d81c74efe767fccc5028/tree/gui/source/gui_main_window.c

1 个答案:

答案 0 :(得分:0)

我找到了一个不错的解决方案(借助C GTK can't open Dialog again after closing via ESC的答案和https://developer.gnome.org/gtk3/stable/GtkWidget.html#GtkWidget-delete-event上的文档):

只需将对话框的delete-event连接到gtk-predefined回调函数gtk_widget_hide_on_delete():

g_signal_connect( G_OBJECT((*this_).use_db_file_chooser), "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL );

当用户关闭对话框对象时,不会销毁它。