我有一個跨平臺的應用程序,它具有一個坐在托盤中的gtk.StatusIcon和一個右鍵單擊上下文菜單。問題是:在Windows機器上,菜單的位置很糟糕。菜單的頂部從鼠標指針開始,因此大部分菜單延伸到屏幕底部以下。然後可以向上滾動並且可用,但對用戶來說有點痛苦。gtk.StatusIcon和Windows上的gtk.Menu
另一個相關的問題是,如果用戶點擊屏幕上的其他位置,菜單是否可以消失?
我有一個跨平臺的應用程序,它具有一個坐在托盤中的gtk.StatusIcon和一個右鍵單擊上下文菜單。問題是:在Windows機器上,菜單的位置很糟糕。菜單的頂部從鼠標指針開始,因此大部分菜單延伸到屏幕底部以下。然後可以向上滾動並且可用,但對用戶來說有點痛苦。gtk.StatusIcon和Windows上的gtk.Menu
另一個相關的問題是,如果用戶點擊屏幕上的其他位置,菜單是否可以消失?
爲了避免Windows上的「滾動菜單」問題,您需要在「popup-menu」信號回調中將gtk.status_icon_position_menu
替換爲None
。
def popup_menu_cb(status_icon, button, activate_time, menu):
menu.popup(None, None, None, button, activate_time)
菜單將顯示在鼠標光標但這是所有Windows程序是怎麼做的。
不知道如何隱藏它...我發現唯一的工作是按下菜單上的鼠標按鈕並將其釋放到外面。 :P
通過在彈出窗口中啓用leave_notify和enter_notify事件,您可以在鼠標移開時隱藏彈出窗口。然後使用這些設置和清除時間戳。然後,在用gobject.timeout_add()創建的計時器回調中,檢查鼠標是否已經離開彈出菜單一段時間。如果它已經隱藏()彈出並清除計時器。
這裏是事件和計時器回調我使用:
. . .
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的調用有些不穩定,所以定時器是必需的。
順便說一句,這只是在Windows中必需的,因爲在Linux中您可以單擊其他地方,彈出窗口將關閉。
我發現一個解決方案來修復彈出菜單不會隱藏在Windows上的問題。
只需添加如下代碼(我的代碼是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頂層窗口並抓住焦點,並在焦點出來時添加破壞功能。
太好了,謝謝! 這個其他問題並不是什麼大不了的,我想我可以忍受它。 – wodemoneke 2009-07-16 18:11:38