2009-07-16 5 views
4

트레이에 gtk.StatusIcon이 있고 크로스 컨텍스트 메뉴가 마우스 오른쪽 버튼으로 클릭되어있는 크로스 플랫폼 앱이 있습니다. 문제는 : Windows 컴퓨터에서 메뉴 배치가 끔찍한 것입니다. 메뉴 상단은 마우스 포인터에서 시작하므로 대부분의 메뉴는 화면 아래쪽으로 확장됩니다. 그러면 스크롤 업하여 사용할 수 있지만 사용자에게는 약간의 고통입니다.gtk.StatusIcon 및 Windows의 gtk.Menu

또 다른 관련 질문은 사용자가 화면의 다른 곳을 클릭하면 메뉴를 사라지게 할 수 있습니까?

답변

3

Windows에서이 "스크롤 메뉴"문제를 피하려면 "팝업 메뉴"신호 콜백에서 gtk.status_icon_position_menuNone으로 바꿔야합니다.

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()로 만든 타이머 콜백에서 일정 시간 동안 마우스가 팝업 메뉴에서 벗어 났는지 확인합니다. 그런 다음 팝업을 숨기고() 타이머를 지 웁니다. 여기

내가 사용하고 행사 및 타이머 콜 백업은 다음과 같습니다

. . . 
    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에서는 다른 곳을 클릭 할 수 있고 팝업이 닫히기 때문에 실제로는 Windows에서만 필요합니다.

1

Windows에서 문제를 숨기지 않는 팝업 메뉴를 수정하는 해결책을 찾았습니다.

그냥 다음 코드를 추가 (내 코드는 C에 있지만 당신은 파이썬이든으로 변경할 수 있습니다) 메뉴 팝업 전에 :

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 최상위 창을 만들고 초점을 잡고 초점을 맞출 때 파괴 기능을 추가하는 것입니다.