5

Tkinter アプリケーションを作成しています。アプリケーションでは、Tk.Menu.post() を使用してコンテキスト メニューをポップアップ表示したいと考えています。

アプリケーションがフォーカスを失ったときにこのメニューを非表示にする方法がわかりません。 別のウィンドウに切り替えても、メニューの「アーティファクト」が残っているため、メニューが一番上にあるため、これを行う必要があります。

メニューにイベントを配置し<FocusOut>ました。これは、メニューにフォーカスがあり、ユーザーがフォーカスを別のアプリケーションに移動した場合にトリガーされます。これはうまくいきます。

メイン アプリケーション ウィンドウにフォーカスがある場合はどうすればよいですか? アプリケーション ウィンドウにイベントを配置<FocusOut>して、メニューを閉じることができます。ただし、メニューにフォーカスを与えると、これが呼び出されてしまい、メニューが閉じます。メニューはメイン アプリケーションとして親を使用して作成されるため<FocusOut>、メニューがフォーカスされたときにメイン アプリがトリガーされる理由がわかりません。

メイン アプリケーション ウィンドウが別のアプリケーションにフォーカスを失っていることと、メニューにフォーカスを失っていることを区別するにはどうすればよいですか?

ユーザーにメインウィンドウへの入力を継続してもらいたいので、tk_popup() を使用したくありません。(メニューの使用はオプションです)。

@Brad Lanamのおかげで、私が含めた解決策を思いつきました:

from Tkinter import *

class App(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self, *args, **kwargs)

        self.entry = Entry(self)
        self.entry.grid(padx=30, pady=30)
        self.entry.focus_set()
        self.entry.bind("<Tab>", self.put_menu)
        self.entry.bind("<Down>", self.set_focus_on_menu)

        self.menu = Menu(self, tearoff=False)
        self.menu.add_command(label="test")
        self.menu.bind("<FocusOut>", self.destroy_menu)


        self.bind("<FocusIn>", self.app_got_focus)
        self.bind("<FocusOut>", self.app_lost_focus)
        self.bind("<3>", self.put_menu)


    def app_got_focus(self, event):
        self.config(background="red")

    def app_lost_focus(self, event):
        self.config(background="grey")

        ######## SOLUTION BEGIN #########
        if self.focus_get() != self.menu:
            self.destroy_menu(event)
        ######## SOLUTION END ###########

    def set_focus_on_menu(self, event):
        self.menu.focus_set()

    def menu_got_focus(self, event):
        self.menu.activate(0)

    def put_menu(self, event):
        self.menu.post(self.winfo_x() + self.entry.winfo_x(), self.winfo_y() + self.entry.winfo_y()+20)

    def destroy_menu(self, event):
        self.menu.destroy()

app = App()

app.mainloop()
4

1 に答える 1

3

self.focus_get()フォーカスのあるオブジェクトを返します。これは、フォーカスを受け取るメニューと他のアプリケーションを区別するために使用できます。

たとえば、フォーカスが別のアプリケーションに移動したときにメニューを削除するには、次のようにします。

def app_lost_focus(self, event):
    if self.focus_get() != self.menu:
        self.destroy_menu(event)
    
于 2014-09-20T01:00:57.037 に答える