Tkinter 绑定回调以激活 window
Tkinter bind callback to activating a window
我正在 Python 3 中编写一个 Tkinter 应用程序,我创建了一个自定义标题栏(每个 Windows 应用程序顶部的栏,带有应用程序名称、关闭按钮等.).我实现这一点的方法是创建一个不可见的 window(我们称之为 window test
)来控制主应用程序 window 的行为(我们将调用 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
window 被最小化时,Main App
window 也会被最小化,这是预期的。
问题是,每当 test
window 激活时,Main App
window 也不会激活。例如,如果另一个应用程序覆盖了 Main App
但 test
没有最小化,我需要在 Windows 任务栏中单击三次 test
图标才能显示它。
我想知道是否有办法解决这个问题,例如:
self.master.bind(<some_command>, self.some_other_command)
但是,我无法在任何地方找到 bind
命令的完整列表。
这是解决此问题的好方法,还是我应该做的其他事情?
此外,我注意到使用 self.overrideredirect(1)
会导致 windows 产生的阴影消失,这会导致 windows 在我的 'merge together' 应用程序中重叠,因为背景颜色相同。有没有办法把阴影加回来?
提前致谢。
我为遇到类似问题的其他人找到了解决方案。您可以在不可见的 window 中创建一个 'dummy' 按钮,当 window 处于焦点时该按钮将变为活动状态。然后,您可以调用一个将主应用程序 window 置于焦点的函数。
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
class 中的 __init__
:
self.master.bind('<FocusIn>', self.on_root_deiconify)
我正在 Python 3 中编写一个 Tkinter 应用程序,我创建了一个自定义标题栏(每个 Windows 应用程序顶部的栏,带有应用程序名称、关闭按钮等.).我实现这一点的方法是创建一个不可见的 window(我们称之为 window test
)来控制主应用程序 window 的行为(我们将调用 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
window 被最小化时,Main App
window 也会被最小化,这是预期的。
问题是,每当 test
window 激活时,Main App
window 也不会激活。例如,如果另一个应用程序覆盖了 Main App
但 test
没有最小化,我需要在 Windows 任务栏中单击三次 test
图标才能显示它。
我想知道是否有办法解决这个问题,例如:
self.master.bind(<some_command>, self.some_other_command)
但是,我无法在任何地方找到 bind
命令的完整列表。
这是解决此问题的好方法,还是我应该做的其他事情?
此外,我注意到使用 self.overrideredirect(1)
会导致 windows 产生的阴影消失,这会导致 windows 在我的 'merge together' 应用程序中重叠,因为背景颜色相同。有没有办法把阴影加回来?
提前致谢。
我为遇到类似问题的其他人找到了解决方案。您可以在不可见的 window 中创建一个 'dummy' 按钮,当 window 处于焦点时该按钮将变为活动状态。然后,您可以调用一个将主应用程序 window 置于焦点的函数。
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
class 中的 __init__
:
self.master.bind('<FocusIn>', self.on_root_deiconify)