TKINTER将回调绑定到激活窗口



我正在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 App,但是test没有最小化,我需要单击Windows任务栏中的test图标,以显示它。

我想知道是否有一种方法可以使用以下方式解决此问题。

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)

最新更新