我已经开发了一个弹出窗口(非装饰)使用GTK和Glade工具在C.
当一个按钮点击时,它的父窗口弹出.当用户点击此窗口时,我想销毁或隐藏此弹出窗口.用户可以点击父窗口或任何其他窗口.
我试图捕获GDK_FOCUS_CHANGE事件,但是我无法捕获此事件.有没有办法实现这一点?我怎么知道点击是在其他窗口然后弹出窗口?怎么清楚弹出窗口已经失去了重点?
所以我可以隐藏它.
相关代码如下:
当一个按钮点击时,它的父窗口弹出.当用户点击此窗口时,我想销毁或隐藏此弹出窗口.用户可以点击父窗口或任何其他窗口.
我试图捕获GDK_FOCUS_CHANGE事件,但是我无法捕获此事件.有没有办法实现这一点?我怎么知道点击是在其他窗口然后弹出窗口?怎么清楚弹出窗口已经失去了重点?
所以我可以隐藏它.
相关代码如下:
/* * 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,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; }
在这里,当用户点击父窗口或其他窗口时,我无法隐藏此弹出窗口.我该怎么做?
我必须坚持使用Gtk 2.14版本.
解决方法
变化:
>从GTK_WINDOW_POPUP切换到GTK_WINDOW_TOPLEVEL,反直觉,但我无法弄清楚如何获得弹出窗口来接受焦点.
>添加GTK_WINDOW暗示,以防止弹出从任务栏和寻呼机表示
>有意设置焦点在弹出窗口
>设置与gtk_widget_set_events的GDK_WINDOW(用于下一步骤需要)GDK_FOCUS_CHANGE_MASK
>连接到弹出窗口的焦点事件
>更改信号处理程序来处理不同的信号
我还建议阅读GTK源,看看它们如何处理弹出窗口的工具提示和菜单,当它们被显示…但是这些通常是基于鼠标移动范围,而不是弹出失去焦点本身毁坏.
#include static void on_popup_clicked (GtkButton*,GtkWidget*); gboolean on_popup_focus_out (GtkWidget*,GdkEventFocus*,gpointer); int main (int argc,char *argv[]) { GtkWidget *window,*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); 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),(gpointer) window); vBox = gtk_vBox_new (FALSE,3); gtk_Box_pack_end (GTK_Box (vBox),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); 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),&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; }