通过ESC关闭后,C GTK无法再次打开Dialog

时间:2016-01-01 22:17:00

标签: c dialog gtk gtk3

我有一个名为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;
}

here

这也可以用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(小部件)'失败

如何解决这个问题?

1 个答案:

答案 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处理所有的回复处理。