2009-11-17 14 views
11

外のユーザーclickesがボタンをクリックしたときに親ウィンドウの上にC. このポップアップでGTK +や空き地のツールを使用して(非装飾された)1つのポップアップウィンドウをIを開発しているに。ユーザーがこのウィンドウをクリックしたときに、このポップアップウィンドウを破棄または非表示にしたい。ユーザーは親ウィンドウまたは他のウィンドウをクリックできます。 私は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, 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バージョンに固執する必要があります。

+0

質問を再投稿しないでください。これは、(もっと良く提示された)http://stackoverflow.com/questions/1740947/problem-with-gtk-popup-window-focus-change-event-handlingのように思われます。 – mlibby

+0

私はこれを今後世話します。 – kbalar

答えて

8

変更:

  • GTK_WINDOW_TOPLEVELからGTK_WINDOW_POPUPからスイッチ、直感に反するが、私はフォーカスを受け入れるようにポップアップを取得する方法を見つけ出すことができませんでした。
  • 意図ポップアップウィンドウ
  • にフォーカスを設定gtk_windowタスクバーで表示からポップアップを防止するためのヒントとページャ
  • を追加する(次のステップのために必要)
  • に接続gtk_widget_set_eventsGDK_WINDOWGDK_FOCUS_CHANGE_MASKを設定しますポップアップウィンドウのfocus-out-event
  • 異なる信号を処理するための変更のシグナルハンドラを

私はwoulまた、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, *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; 
} 
+0

それは働いている!これにして見ているため 感謝。 – kbalar

+0

良い取引。この答えがあなたに役立つ場合は、答えの横にある大きなチェックマークをクリックしてください。:) – mlibby

+0

偉大な解決策が、1つの問題があります:メインウィンドウは、境界を色分けして(Windows 7)フォーカスの変更を視覚的に登録しています。これは、(偽の)ポップアップウィンドウでは起こりません。これを防ぐための考え? – schlamar

2

ポップアップウィンドウにキーボードフォーカスを設定する必要はありません。

あなたは真のowner_eventsとGDK_BUTTON_PRESS_MASK GdkEventMask引数でgdk_pointer_grab(...)を使用してpopup_window->windowにマウスをキャプチャする必要があります。

その後"button-press-event"にごpopup_windowを接続します。その内部のハンドラを隠す/あなたのpopup_windowを破棄し、イベントの座標が負であるかpopup_windowの大きさより大きい場合はgdk_pointer_ungrab(...)を使用してキャプチャを解放します。

1

もう1つの方法は、親ウィンドウにボタン・プレス・リスナーを追加する方法です。これは、ポップアップウィンドウがまだポップアップのように見えるという利点があります(親とその両方が一度にアクティブになることができます)

#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); 
} 
関連する問題