C GTK 在通过 ESC 关闭后无法再次打开对话框
C GTK can't open Dialog again after closing via ESC
我有一个名为 dlg_open
的对话框,带有一个 btn_cancel_open
按钮。
此对话框在 Buton-Event 和对话框的 close
事件映射到:
void on_btn_cancel_clicked (GtkWidget *widget, signal_map_data *smd) {
#ifdef debug
g_print ("-> on_btn_cancel_clicked\n");
#endif
gtk_widget_hide (gtk_widget_get_toplevel (widget) );
gtk_widget_set_sensitive (smd->widg.wmw.wnd, 1);
}
void on_dlg_close (GtkWidget *widget, signal_map_data *smd) {
#ifdef debug
g_print ("-> on_dlg_close\n");
#endif
gtk_widget_hide (widget);
gtk_widget_set_sensitive (smd->widg.wmw.wnd, 1);
}
这很好用。这是我打开对话框的方式:
void on_btn_open_clicked (GtkWidget *widget, signal_map_data *smd) {
#ifdef debug
g_print ("-> on_btn_open_clicked\n");
#endif
gtk_widget_set_sensitive (smd->widg.wmw.wnd, 0);
gtk_widget_show (smd->widg.wdow.dlg_open);
}
我的问题是,当我通过按键 ESC
关闭对话框时,我无法再次打开它,主 window 丢失了它的 sensitivity
,但是对话框没有' 出现,并且在控制台打印出一条错误消息:
Gtk-CRITICAL **: gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed
当我通过 cancel-button
关闭对话框时,它工作正常,我可以重新打开对话框 window。
只是 ESC
的问题。
但是where/why?
根据 andlabs 进行编辑 答案:(!!已更新!!)
我从on_dlg_close
功能改成了response
管理功能:
void on_dlg_response (GtkDialog *dlg, gint r_id, signal_map_data *smd) {
#ifdef debug
g_print ("-> on_dlg_response\n");
#endif
switch (r_id) {
case GTK_RESPONSE_DELETE_EVENT: {
gtk_widget_hide (dlg);
gtk_widget_set_sensitive (smd->widg.wmw.wnd, 1);
}
}
}
我还添加了 delete-event
:
gboolean on_dlg_delete (GtkWidget *widget, GdkEvent *event, signal_map_data *smd) {
#ifdef debug
g_print ("-> on_dlg_delete\n");
#endif
return FALSE;
}
这也适用于使用 ESC 关闭对话框。但是仍然存在同样的问题,当我通过 ESC
按钮关闭对话框时无法重新打开对话框,出现相同的错误:
-> on_dlg_response
-> on_dlg_delete
-> on_btn_add_clicked
(main:16478): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkLabel'
(main:16478): Gtk-CRITICAL **: gtk_label_set_text: assertion 'GTK_IS_LABEL (label)' failed
(main:16478): Gtk-CRITICAL **: gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed
如何解决这个问题?
您不想连接到 close
;对于按下的 Escape 键,那是 仅。相反,连接到 response
并检查已知响应。
一个 GtkDialog 就是一个 GtkWindow;默认情况下,当您单击关闭按钮时,它会被销毁。您将需要连接到 delete-event
以规避此行为。 (gtk_dialog_run()
为您完成此操作,这就是为什么单击具有该功能的对话框 运行 上的关闭按钮而不是手动不会破坏小部件的原因。当然,覆盖仅在持续时间内生效电话。)
当然,这意味着您需要特殊处理才能在别处关闭对话框。 GtkDialog 安装它自己的信号处理程序,在继续删除之前发出 response
和 GTK_RESPONSE_DELETE_EVENT
。如果您只使用 g_signal_connect()
,您的代码将在 运行 之前有机会 运行,并且您需要在两个地方设置对话框关闭逻辑。我不知道您是否可以使用 g_signal_connect_after()
将自己置于 GtkDialog 的处理程序和默认处理程序之间,但值得一试。如果这确实有效,那么您的 delete-event
可能只是一个 return TRUE;
,而您在 response
中进行所有响应处理。
我有一个名为 dlg_open
的对话框,带有一个 btn_cancel_open
按钮。
此对话框在 Buton-Event 和对话框的 close
事件映射到:
void on_btn_cancel_clicked (GtkWidget *widget, signal_map_data *smd) {
#ifdef debug
g_print ("-> on_btn_cancel_clicked\n");
#endif
gtk_widget_hide (gtk_widget_get_toplevel (widget) );
gtk_widget_set_sensitive (smd->widg.wmw.wnd, 1);
}
void on_dlg_close (GtkWidget *widget, signal_map_data *smd) {
#ifdef debug
g_print ("-> on_dlg_close\n");
#endif
gtk_widget_hide (widget);
gtk_widget_set_sensitive (smd->widg.wmw.wnd, 1);
}
这很好用。这是我打开对话框的方式:
void on_btn_open_clicked (GtkWidget *widget, signal_map_data *smd) {
#ifdef debug
g_print ("-> on_btn_open_clicked\n");
#endif
gtk_widget_set_sensitive (smd->widg.wmw.wnd, 0);
gtk_widget_show (smd->widg.wdow.dlg_open);
}
我的问题是,当我通过按键 ESC
关闭对话框时,我无法再次打开它,主 window 丢失了它的 sensitivity
,但是对话框没有' 出现,并且在控制台打印出一条错误消息:
Gtk-CRITICAL **: gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed
当我通过 cancel-button
关闭对话框时,它工作正常,我可以重新打开对话框 window。
只是 ESC
的问题。
但是where/why?
根据 andlabs 进行编辑 答案:(!!已更新!!)
我从on_dlg_close
功能改成了response
管理功能:
void on_dlg_response (GtkDialog *dlg, gint r_id, signal_map_data *smd) {
#ifdef debug
g_print ("-> on_dlg_response\n");
#endif
switch (r_id) {
case GTK_RESPONSE_DELETE_EVENT: {
gtk_widget_hide (dlg);
gtk_widget_set_sensitive (smd->widg.wmw.wnd, 1);
}
}
}
我还添加了 delete-event
:
gboolean on_dlg_delete (GtkWidget *widget, GdkEvent *event, signal_map_data *smd) {
#ifdef debug
g_print ("-> on_dlg_delete\n");
#endif
return FALSE;
}
这也适用于使用 ESC 关闭对话框。但是仍然存在同样的问题,当我通过 ESC
按钮关闭对话框时无法重新打开对话框,出现相同的错误:
-> on_dlg_response
-> on_dlg_delete
-> on_btn_add_clicked
(main:16478): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkLabel'
(main:16478): Gtk-CRITICAL **: gtk_label_set_text: assertion 'GTK_IS_LABEL (label)' failed
(main:16478): Gtk-CRITICAL **: gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed
如何解决这个问题?
您不想连接到 close
;对于按下的 Escape 键,那是 仅。相反,连接到 response
并检查已知响应。
一个 GtkDialog 就是一个 GtkWindow;默认情况下,当您单击关闭按钮时,它会被销毁。您将需要连接到 delete-event
以规避此行为。 (gtk_dialog_run()
为您完成此操作,这就是为什么单击具有该功能的对话框 运行 上的关闭按钮而不是手动不会破坏小部件的原因。当然,覆盖仅在持续时间内生效电话。)
当然,这意味着您需要特殊处理才能在别处关闭对话框。 GtkDialog 安装它自己的信号处理程序,在继续删除之前发出 response
和 GTK_RESPONSE_DELETE_EVENT
。如果您只使用 g_signal_connect()
,您的代码将在 运行 之前有机会 运行,并且您需要在两个地方设置对话框关闭逻辑。我不知道您是否可以使用 g_signal_connect_after()
将自己置于 GtkDialog 的处理程序和默认处理程序之间,但值得一试。如果这确实有效,那么您的 delete-event
可能只是一个 return TRUE;
,而您在 response
中进行所有响应处理。