4

我有一个跨平台应用程序,它的托盘中有一个 gtk.StatusIcon 和一个右键单击上下文菜单。问题是:在 Windows 机器上,菜单的位置很糟糕。菜单的顶部从鼠标指针开始,因此大部分菜单都延伸到屏幕底部下方。然后可以向上滚动并且可以使用,但这对用户来说有点痛苦。

另一个相关问题,如果用户点击屏幕上的其他地方,是否可以让菜单消失?

4

3 回答 3

3

为避免在 Windows 上出现此“滚动菜单”问题,您需要在“弹出菜单”信号回调中替换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

于 2009-07-16T18:04:37.273 回答
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 的调用有些不稳定,因此需要使用计时器。

顺便说一句,这实际上仅在 Windows 中是必需的,因为在 Linux 中,您可以单击其他地方并且弹出窗口将关闭。

于 2010-07-17T02:52:21.273 回答
1

我找到了修复弹出菜单的解决方案,不会在 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的顶级窗口并抓住焦点,并在焦点消失时添加销毁功能。

于 2017-07-11T21:10:04.740 回答