簡體   English   中英

Tkinter 綁定回調以激活窗口

[英]Tkinter bind callback to activating a window

我正在用 Python 3 編寫 Tkinter 應用程序,並且創建了一個自定義標題欄(每個 Windows 應用程序頂部的欄,帶有應用程序名稱、關閉按鈕等)。 我實現這一點的方法是創建一個不可見的窗口(我們稱之為窗口test )來控制主應用程序窗口的行為(我們稱之為Main App )。 下面是一段測試代碼,說明了這一點:

from tkinter import Tk, Toplevel
from tkinter.ttk import Button, Label, Frame, Style


class NewRoot(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.attributes('-alpha', 1.0)  # This is normally set to 0.0


class MyMain(Toplevel):
    def __init__(self, master):
        Toplevel.__init__(self, master)
        self.overrideredirect(1)
        self.geometry('750x650+400+600')

        self.style = Style()

        self.style.configure('TTitleBar.Label',
                             width=8,
                             relief='flat',
                             foreground='red',
                             background='red',
                             anchor='center',
                             borderwidth=-1)

        self.style.configure('TMainWindow.Label',
                             width=8,
                             relief='flat',
                             background='blue',
                             anchor='center',
                             borderwidth=-1)

        self.tk_setPalette(background='green')

        self.x_win = None
        self.y_win = None
        self.start_x = None
        self.start_y = None

        # make a frame for the title bar
        title_bar = Frame(self, style='TTitleBar.Label')
        title_bar.grid(row=0, column=0, sticky='wn')

        label = Label(title_bar, text='Main App', style='TMainWindow.Label')
        label.grid(row=0, column=0, padx=(4, 2), pady=(4, 0), sticky='nw')

        minimize_button = Button(title_bar, text='MIN', command=self.minimize_window,
                                 style='TMainWindow.Label', takefocus=False)
        minimize_button.grid(row=0, column=2, padx=(563.5, 0), sticky='nw')

        maximise_button = Button(title_bar, text='MAX', command=self.maximize_window,
                                 style='TMainWindow.Label', takefocus=False)
        maximise_button.grid(row=0, column=3, pady=(1.4, 0), sticky='nw')

        close_button = Button(title_bar, text='CLOSE', command=self.close_window,
                              style='TMainWindow.Label', takefocus=False)
        close_button.grid(row=0, column=4, sticky='nw')

        window = Frame(self)
        window.grid(row=1, column=0, sticky='ne')

        # bind title bar motion to the move window function
        title_bar.bind('<B1-Motion>', self.move_window)
        title_bar.bind('<Button-1>', self.get_pos)
        self.master.bind("<Map>", self.on_root_deiconify)
        self.master.bind("<Unmap>", self.on_root_iconify)

        self.mainloop()

    def minimize_window(self):
        self.master.iconify()

    def maximize_window(self):
        pass

    def close_window(self):
        self.master.destroy()

    def on_root_iconify(self, event):
        # print('unmap')
        self.withdraw()

    def on_root_deiconify(self, event):
        # print('map')
        self.deiconify()

    def get_pos(self, event):
        self.x_win = self.winfo_x()
        self.y_win = self.winfo_y()
        self.start_x = event.x_root
        self.start_y = event.y_root
        self.y_win = self.y_win - self.start_y
        self.x_win = self.x_win - self.start_x

    def move_window(self, event):
        # print('+{0}+{1}'.format(event.x_root, event.y_root))
        self.geometry('+{0}+{1}'.format(event.x_root + self.x_win, event.y_root + self.y_win))

        self.start_x = event.x_root
        self.start_y = event.y_root


if __name__ == '__main__':

    root = NewRoot()
    root.title('test')
    app = MyMain(root)

在上面的代碼中,每當test窗口最小化時, Main App窗口也會最小化,這按預期工作。

問題是,每當test窗口處於活動狀態時, Main App窗口也不會變為活動狀態。 例如,如果另一個應用程序覆蓋Main Apptest未最小化,我需要單擊 Windows 任務欄中的test圖標 3 次才能顯示它。

我想知道是否有辦法使用以下方法解決此問題:

self.master.bind(<some_command>, self.some_other_command)

但是,我在任何地方都找不到bind命令的完整列表。 這是解決這個問題的好方法,還是我應該做其他事情?

另外,我注意到使用self.overrideredirect(1)會導致窗口產生的陰影消失,這會導致我的應用程序中的重疊窗口“合並在一起”,因為背景顏色是相同的。 有沒有辦法重新添加陰影?

先感謝您。

我為其他有類似問題的人找到了解決方案。 您可以在不可見窗口中創建一個“虛擬”按鈕,當窗口處於焦點時該按鈕將變為活動狀態。 然后,您可以調用一個將主應用程序窗口置於焦點的函數。

class NewRoot(Tk):
def __init__(self):
    Tk.__init__(self)
    self.attributes('-alpha', 0.0)
    entry = Button()
    entry.pack()
    entry.focus_set()
    entry.pack_forget()

然后將其添加到MyMain類中的__init__中:

self.master.bind('<FocusIn>', self.on_root_deiconify)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM