2009-07-16 7 views
4

トレイにgtk.StatusIconが置かれたクロスプラットフォームのアプリケーションと右クリックのコンテキストメニューがあります。問題は、Windowsマシンではメニューの配置がひどいことです。メニューの上部はマウスポインタから始まり、ほとんどのメニューは画面の下に広がります。これはスクロールアップされて使用可能ですが、ユーザーにとっては少し苦労します。gtk.StatusIconとWindowsのgtk.Menu

もう1つの関連する質問は、ユーザーが画面上の他の場所をクリックするとメニューを消すことができますか?

答えて

3

Windowsのこの「スクロールメニュー」の問題を回避するには、「popup-menu」シグナルコールバックでをNoneに置き換える必要があります。

def popup_menu_cb(status_icon, button, activate_time, menu): 
    menu.popup(None, None, None, button, activate_time) 

メニューは、マウスカーソルの上に表示されますが、それはすべてのWindowsプログラムがそれを行う方法です。

それを隠す方法はわかりません...私が見つけた唯一のことは、メニュー上でマウスボタンを押して外にリリースすることです。 :P

+0

ありがとう! この他の問題はそれほど大きな問題ではありません。私はそれで生きることができると思います。 – wodemoneke

2

ポップアップでleave_notifyイベントとenter_notifyイベントを有効にすることで、マウスが離れたときにポップアップを非表示にすることができます。次に、これらを使用してタイムスタンプを設定してクリアします。次に、gobject.timeout_add()で作成されたタイマーコールバックで、一定時間マウスがポップアップメニューから離れていないかどうかを確認します。それがあれば、ポップアップをhide()してタイマーをクリアします。ここで

は、私が使用しているイベントやタイマーコールバックです:

. . . 
    self.mouse_in_tray_menu = None 
    gobject.timeout_add(500, self.check_hide_popup) 
. . . 

def on_tray_menu_enter_notify_event(self, widget, event, data = None): 
    self.mouse_in_tray_menu = None 


def on_tray_menu_leave_notify_event(self, widget, event, data = None): 
    self.mouse_in_tray_menu = event.time + 1 # Timeout in 1 sec 


def check_hide_popup(self, data = None): 
    if self.mouse_in_tray_menu and self.mouse_in_tray_menu < time.time(): 
     self.tray_menu.hide() 
     self.mouse_in_tray_menu = None 

    return True # Keep the timer callback running 

あなたはすべての時間を実行しているタイマーを維持する必要はありませんが、それは簡単ですし、私も他のもののためにそれを使用しています。 enter_notifyとleave_notifyへの呼び出しは多少不安定なので、タイマーが必要です。

ところで、これは実際にはLinuxで必要なのは、Linuxでは他の場所をクリックしてポップアップを閉じることができるからです。

1

ポップアップメニューを修正する解決策は、ウィンドウ上の問題を隠すことはできません。

だけでメニューをポップアップする前に(私のコードはCであるが、あなたはPythonや何にそれを変更することができます)、次のコードを追加します。

GtkWidget *hidden_window; 
hidden_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 
gtk_window_set_resizable (GTK_WINDOW (hidden_window), FALSE); 
gtk_window_set_decorated (GTK_WINDOW (hidden_window), FALSE); 
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (hidden_window), TRUE); 
gtk_window_set_skip_pager_hint (GTK_WINDOW (hidden_window), TRUE); 
gtk_widget_set_size_request (hidden_window, 0, 0); 
gtk_window_set_transient_for (GTK_WINDOW (hidden_window), GTK_WINDOW (widget)); //widget is your main window, this is to hide dummy window from taskbar 
gtk_window_set_position (GTK_WINDOW (hidden_window), GTK_WIN_POS_MOUSE); 

gtk_widget_set_events (hidden_window, GDK_FOCUS_CHANGE_MASK); 
g_signal_connect (G_OBJECT (hidden_window), 
       "focus-out-event", 
       G_CALLBACK (on_hidden_window_focus_out), 
       NULL); 
gtk_widget_show_all (hidden_window); 
gtk_widget_grab_focus (hidden_window); 

もこの機能を追加します。

static void on_hidden_window_focus_out(GtkWidget *widget, 
       GdkEventFocus *event, 
       gpointer data) 
{ 
    gtk_widget_destroy (widget); 
} 

1x1のトップレベルウィンドウをマウスの位置に作成してフォーカスを取得し、フォーカスを外すと破壊機能を追加することです。