加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

当用户在窗口外点击时,如何隐藏Gtk Popup窗口

发布时间:2020-12-16 03:07:31 所属栏目:百科 来源:网络整理
导读:我已经开发了一个弹出窗口(非装饰)使用GTK和Glade工具在C. 当一个按钮点击时,它的父窗口弹出.当用户点击此窗口时,我想销毁或隐藏此弹出窗口.用户可以点击父窗口或任何其他窗口. 我试图捕获GDK_FOCUS_CHANGE事件,但是我无法捕获此事件.有没有办法实现这一点?
我已经开发了一个弹出窗口(非装饰)使用GTK和Glade工具在C.
当一个按钮点击时,它的父窗口弹出.当用户点击此窗口时,我想销毁或隐藏此弹出窗口.用户可以点击父窗口或任何其他窗口.
我试图捕获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;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读