C GTK can't open Dialog again after closing vi

2019-09-06 16:18发布

问题:

I have a Dialog called dlg_open with an btn_cancel_open Button. This dialog is mapped at the Buton-Event and the close Event of the dialog to:

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);
}

This works fine. And here is how I open the dialog:

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);
}

My problem is, that when I close the Dialog via keystroke ESC, I can't open it again, the main window looses its sensitivity, but the dialog doesn't appear, and at the console is a error message printed out:

Gtk-CRITICAL **: gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed

When I close the dialog via the cancel-button itt works fine and I can reopen the dialog window.

Just a problem with the ESC .

But where/why?

EDIT ACCORDING TO andlabs ANSWER: (!!UPDATED!!)

I changed from a on_dlg_close function to a response management function:

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);
    }
  }
}

I've also added the 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;
}

This also works to close the dialog with ESC. But there is still the same problem that I can't reopen the dialog when I closed it via ESC Button with same error:

-> 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

How to solve this problem?

回答1:

You don't want to connect to close; that's only for the Escape key being pressed. Instead, connect to response and check for known responses.

A GtkDialog is a GtkWindow; by default, when you click the Close button, it is destroyed. You will need to connect to delete-event to circumvent this behavior. (gtk_dialog_run() does this for you, which is why clicking the Close button on a dialog run with that function instead of manually doesn't destroy the widget. Of course, the override only takes effect for the duration of the call.)

Of course this means you'll need special handling for closing the dialog elsewhere. GtkDialog installs its own signal handler that issues a response with GTK_RESPONSE_DELETE_EVENT before going ahead with the deletion. If you just use g_signal_connect(), your code will run before that one will ever get a chance to run, and you'll need to have the dialog closing logic in two places. I don't know if you can use g_signal_connect_after() to put yourself in between GtkDialog's handler and the default, but it's worth trying. If that actually does work, then your delete-event could just be a return TRUE; and you do all your response handling in response instead.



标签: c dialog gtk gtk3