在 Windows 下,我更喜欢在用户尝试重新定位窗口时禁用该窗口,但显然这不是跨平台选项。另一种选择是使用 overrideredirect 标志来中止移动。只是将窗口重新定位到所需的位置就会导致整个屏幕闪烁。使用 overrideredirect,您仍然会遇到闪烁,但在同一位置,这给我一种尝试访问 MS-Windows 上禁用的窗口的感觉,其中它们blink窗户。
请注意,此代码应该在边缘情况下使用,例如模态窗口 https://en.wikipedia.org/wiki/Modal_window。它通常被认为是烦人的(!),但对于仅在需要时出现的关键错误/消息,您可以而且也许应该能够做到这一点。
该技术的解释更深入一些:
- 当用户尝试重新定位窗口时会触发配置事件
- The sequence
surpress_move
is called and checks the event details to match the specific case we are looking for:
- 第一个条件调用的小部件不是根窗口的子窗口,它必须是根窗口
- x 和 y 细节与我们指定的不同。
- 我们将 overrideredirect 标志设置为 true,这会导致未装饰的窗口(没有标题栏),因此没有移动,因为操作系统窗口管理器不再管理移动。
- 我们将窗户重新定位回我们想要的位置并再次装饰窗户。
这是代码:
import tkinter as tk
XCOORD = 0
YCOORD = 0
def surpress_move(event):
if event.widget == root:
if event.x != XCOORD or event.y != YCOORD:
#event.widget.attributes('-disabled',True) #winows only
event.widget.overrideredirect(True)
event.widget.geometry(f'+{XCOORD}+{YCOORD}')
event.widget.overrideredirect(False)
#event.widget.attributes('-disabled',False)
root = tk.Tk()
root.bind('<Configure>',surpress_move)
root.mainloop()
如果您想使用 tkinter 锚定常量,您可以执行以下操作:
import tkinter as tk
root = tk.Tk()
def get_anchor_coords(anchor):
if anchor in ('NW',tk.NW):
return 0,0
elif anchor in ('NE',tk.NE):
return root.winfo_screenwidth-root.winfo_width(),0
###for South you should find the workspace or a constant for the taskbar
elif anchor in ('SW', tk.SW):
return 0,root.winfo_screenheight()-root.winfo_height()
elif anchor in ('SE', tk.SE):
return (root.winfo_screenwidth-root.winfo_width(),
root.winfo_screenheight()-root.winfo_height())
else:
raise ValueError(f'anchor: {repr(anchor)}, not recognized!')
def surpress_move(event, anchor):
if event.widget == root:
xy = event.x,event.y
anchor_coords = get_anchor_coords(anchor)
if xy != anchor_coords:
#event.widget.attributes('-disabled',True)
event.widget.overrideredirect(True)
event.widget.geometry(f'+{anchor_coords[0]}+{anchor_coords[1]}')
event.widget.overrideredirect(False)
#event.widget.attributes('-disabled',False)
root.bind('<Configure>',lambda e:surpress_move(e,'wW'))
root.mainloop()