我有一个名为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
关闭对话框时,我无法再次打开它,主窗口会丢失其sensitivity
,但对话框没有出现,并在控制台打印出一条错误消息:
Gtk-CRITICAL **: gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed
当我通过cancel-button
关闭对话框时它工作正常,我可以重新打开对话框窗口。
ESC
只是一个问题。
但是在哪里/为什么?
根据 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
(主要:16478):GLib-GObject-WARNING **:投射到' GtkLabel'
的无效指针无效(主要:16478):Gtk-CRITICAL **:gtk_label_set_text:断言' GTK_IS_LABEL(标签)'失败
(主要:16478):Gtk-CRITICAL **:gtk_widget_show:断言' GTK_IS_WIDGET(小部件)'失败
如何解决这个问题?
答案 0 :(得分:1)
您不想连接到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
处理所有的回复处理。