English 中文(简体)
用户在窗口外点击时如何隐藏Gtk Popup Window
原标题:How to hide Gtk Popup Window when user clickes outside the window
  • 时间:2009-11-17 09:11:50
  •  标签:
  • c
  • gtk

I have developed one popup window (Non decorated) using GTK+ and glade tool in C. It popup on its parent window when a button clicked. I want to destroy or hide this popup window when user clicks out side this window. User can click on parent window or any other window. I have tried to capture GDK_FOCUS_CHANGE event but I am not able to capture this event. Is there any way to achieve this? How do I know that click is on other window then pop up window? How is it clear that pop up window has lost it s focus? So that I can hide it. The relevant code is as follow:

/*
 * Compile me with:

 gcc -o popup popup.c $(pkg-config --cflags --libs gtk+-2.0 gmodule-2.0)
*/

#include <gtk/gtk.h>

static void on_popup_clicked (GtkButton*, GtkWidget*);
static gboolean on_popup_window_event(GtkWidget*, GdkEventExpose*);

int main (int argc, char *argv[])
{
    GtkWidget *window, *button, *vbox;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (window), "Parent window");
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
    gtk_widget_set_size_request (window, 300, 300);
    gtk_window_set_position (GTK_WINDOW (window),GTK_WIN_POS_CENTER);

    button = gtk_button_new_with_label("Pop Up");
    g_signal_connect (G_OBJECT (button), "clicked",G_CALLBACK (on_popup_clicked),(gpointer) window);

    vbox = gtk_vbox_new (FALSE, 3);
    gtk_box_pack_end(GTK_BOX (vbox), button, FALSE, FALSE, 5);
    gtk_container_add (GTK_CONTAINER (window), vbox);

    gtk_widget_show_all (window);
    gtk_main ();
    return 0;
}

void on_popup_clicked (GtkButton* button, GtkWidget* pWindow)
{
    GtkWidget *popup_window;
    popup_window = gtk_window_new (GTK_WINDOW_POPUP);
    gtk_window_set_title (GTK_WINDOW (popup_window), "Pop Up window");
    gtk_container_set_border_width (GTK_CONTAINER (popup_window), 10);
    gtk_window_set_resizable(GTK_WINDOW (popup_window), FALSE);
    gtk_window_set_decorated(GTK_WINDOW (popup_window), FALSE);
    gtk_widget_set_size_request (popup_window, 150, 150);
    gtk_window_set_transient_for(GTK_WINDOW (popup_window),GTK_WINDOW (pWindow));
    gtk_window_set_position (GTK_WINDOW (popup_window),GTK_WIN_POS_CENTER);
    g_signal_connect (G_OBJECT (button), "event",
                        G_CALLBACK (on_popup_window_event),NULL);

    GdkColor color;
    gdk_color_parse("#3b3131", &color);
    gtk_widget_modify_bg(GTK_WIDGET(popup_window), GTK_STATE_NORMAL, &color);


    gtk_widget_show_all (popup_window);
}

gboolean on_popup_window_event(GtkWidget *popup_window, GdkEventExpose *event)
{
    if(event->type == GDK_FOCUS_CHANGE)
        gtk_widget_hide (popup_window);

    return FALSE;
}

在此,当用户在母窗或在其他窗户上点击时,我无法躲藏这一pop窗。 我如何能够这样做?

我必须坚持Gtk+2.14版本。

最佳回答

变化:

  • switch from GTK_WINDOW_POPUP to GTK_WINDOW_TOPLEVEL, counter-intuitive, but I could not figure out how to get a popup to accept focus.
  • add gtk_window hints to prevent popup from showing in taskbar and pager
  • intentionally set the focus on the popup window
  • set the GDK_FOCUS_CHANGE_MASK on the GDK_WINDOW with gtk_widget_set_events (required for the next step)
  • connect to the focus-out-event of the popup window
  • change the signal handler to handle a different signal

我也建议阅读德国地球科学公司+来源,以了解它如何在显示时处理工具倾斜和菜单的流行窗口......但是,这些窗户通常由于从范围移出的烟雾而被毁,而不是因人口流失而失去重点。


#include 

static void on_popup_clicked (GtkButton*, GtkWidget*);
gboolean on_popup_focus_out (GtkWidget*, GdkEventFocus*, gpointer);

int
main (int argc, char *argv[])
{
  GtkWidget *window, *button, *vbox;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Parent window");
  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
  gtk_widget_set_size_request (window, 300, 300);
  gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);

  button = gtk_button_new_with_label ("Pop Up");
  g_signal_connect (G_OBJECT (button),
                    "clicked",
                    G_CALLBACK (on_popup_clicked),
                    (gpointer) window);

  vbox = gtk_vbox_new (FALSE, 3);
  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
  gtk_container_add (GTK_CONTAINER (window), vbox);

  gtk_widget_show_all (window);
  gtk_main ();
  return 0;
}

void
on_popup_clicked (GtkButton* button, GtkWidget* pWindow)
{
  GtkWidget *popup_window;

  popup_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (popup_window), "Pop Up window");
  gtk_container_set_border_width (GTK_CONTAINER (popup_window), 10);
  gtk_window_set_resizable (GTK_WINDOW (popup_window), FALSE);
  gtk_window_set_decorated (GTK_WINDOW (popup_window), FALSE);
  gtk_window_set_skip_taskbar_hint (GTK_WINDOW (popup_window), TRUE);
  gtk_window_set_skip_pager_hint (GTK_WINDOW (popup_window), TRUE);
  gtk_widget_set_size_request (popup_window, 150, 150);
  gtk_window_set_transient_for (GTK_WINDOW (popup_window), GTK_WINDOW (pWindow));
  gtk_window_set_position (GTK_WINDOW (popup_window), GTK_WIN_POS_CENTER);

  gtk_widget_set_events (popup_window, GDK_FOCUS_CHANGE_MASK);
  g_signal_connect (G_OBJECT (popup_window),
                    "focus-out-event",
                    G_CALLBACK (on_popup_focus_out),
                    NULL);

  GdkColor color;
  gdk_color_parse ("#3b3131", &color);
  gtk_widget_modify_bg (GTK_WIDGET (popup_window), GTK_STATE_NORMAL, &color);

  gtk_widget_show_all (popup_window);
  gtk_widget_grab_focus (popup_window);
}

gboolean
on_popup_focus_out (GtkWidget *widget,
                    GdkEventFocus *event,
                    gpointer data)
{
  gtk_widget_destroy (widget);
  return TRUE;
}
问题回答

你不需要把重点放在你们的流行窗口上。

您仅需要掌握以下几条内容:<代码>popup_window->window , 采用<代码>gdk_pointer_grab(......), 真正<代码>的所有人_events和GDK_BUTTON_PRESS_MASKcode>GdkEventMask。

然后,把你pop-窗口与<条码>连接起来。” 手边用<条码>gdk_pointer_ungrab(......)隐藏/播种你,如果喷口坐标为负数或大于你之波-window大小,则该片暗藏/des。

另一种选择是简单地在母窗上添加一个顿新闻听众。 这的好处是,人口窗口仍然像人口一样(父母和自己都可以一度活跃)

#include <stdio.h>
#include <gtk/gtk.h>

static void on_popup_clicked (GtkButton*, GtkWidget*);

gulong handler_id;

gboolean
on_click (GtkWidget *widget,
               GdkEvent  *event,
               gpointer   user_data)
{
  g_signal_handler_disconnect (widget, handler_id);
  gtk_widget_destroy (user_data);
  return TRUE;
}


gboolean
on_popup_focus_out (GtkWidget *widget,
                    GdkEventFocus *event,
                    gpointer data)
{
  gtk_widget_destroy (widget);
  return TRUE;
}


int
main (int argc, char *argv[])
{
  GtkWidget *window, *button, *vbox;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Parent window");
  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
  gtk_widget_set_size_request (window, 300, 300);
  gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);

  button = gtk_button_new_with_label ("Pop Up");
  g_signal_connect (G_OBJECT (button),
                    "clicked",
                    G_CALLBACK (on_popup_clicked),
                    (gpointer) window);

  vbox = gtk_vbox_new (FALSE, 3);
  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
  gtk_container_add (GTK_CONTAINER (window), vbox);

  gtk_widget_show_all (window);
  gtk_main ();
  return 0;
}

void
on_popup_clicked (GtkButton* button, GtkWidget* pWindow)
{
  GtkWidget *popup_window;

  popup_window = gtk_window_new (GTK_WINDOW_POPUP);
  gtk_window_set_title (GTK_WINDOW (popup_window), "Pop Up window");
  gtk_container_set_border_width (GTK_CONTAINER (popup_window), 10);
  gtk_window_set_resizable (GTK_WINDOW (popup_window), FALSE);
  gtk_window_set_decorated (GTK_WINDOW (popup_window), FALSE);
  gtk_window_set_skip_taskbar_hint (GTK_WINDOW (popup_window), TRUE);
  gtk_window_set_skip_pager_hint (GTK_WINDOW (popup_window), TRUE);
  gtk_widget_set_size_request (popup_window, 150, 150);
  gtk_window_set_transient_for (GTK_WINDOW (popup_window), GTK_WINDOW (pWindow));
  gtk_window_set_position (GTK_WINDOW (popup_window), GTK_WIN_POS_CENTER);

  gtk_widget_add_events (popup_window, GDK_FOCUS_CHANGE_MASK);
  gtk_widget_add_events (pWindow, GDK_BUTTON_PRESS_MASK);

  g_signal_connect (G_OBJECT (popup_window),
                    "focus-out-event",
                    G_CALLBACK (on_popup_focus_out),
                    NULL);

  handler_id = g_signal_connect (G_OBJECT (pWindow),
                    "button-press-event",
                    G_CALLBACK (on_click),
                    popup_window);

  GdkColor color;
  gdk_color_parse ("#3b3131", &color);
  gtk_widget_modify_bg (GTK_WIDGET (popup_window), GTK_STATE_NORMAL, &color);

  gtk_widget_show_all (popup_window);
  gtk_widget_grab_focus (popup_window);
}




相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签