【问题标题】:How do I anchor a Tkinter window in my screen (unmovable window)如何在我的屏幕上锚定一个 Tkinter 窗口(不可移动的窗口)
【发布时间】:2022-11-27 05:13:32
【问题描述】:

我试图在特定位置打开一个 tkinter,如果它不可移动会更好。我搜索文档和其他文档,但没有找到任何相关信息。 最好的方法是将顶部或底部固定在一个位置 x、y,如果需要,我可以调整窗口大小。

def my_functions():
    print('task done')
    ws.after(1000, my_functions)

ws.after(1000, my_functions())

【问题讨论】:

  • 我知道使窗口不可移动的唯一方法是使窗口无边界,但是这当然还有其他缺点。
  • 您使用的是哪个操作系统?唯一的tkinter 方法是绑定到"<Configure>"(检查用户是否试图移动窗口)然后将窗口移回。
  • 这是确保没有人愿意使用您的应用程序的好方法。
  • @MadPhysicist 这取决于,如果应用程序具有全屏属性或窗口是自定义对话框,那么它可能有意义固定窗户。虽然我确实同意无法移动的普通窗口的用户体验将被描述为恼人的由我。

标签: python tkinter


【解决方案1】:

在 Windows 下,我更喜欢在用户尝试重新定位窗口时禁用窗口,但显然这不是跨平台选项。另一种选择是使用 overrideredirect 标志来中止移动。只需将窗口重新定位到您想要的位置,就会导致整个屏幕都在闪烁。使用 overrideredirect 你仍然会遇到闪烁但在相同的位置,它让我感觉试图访问 MS-Windows 上禁用的窗口,他们在那里窗户。

请注意,此代码应在modal window 等边缘情况下使用。它通常令人讨厌(!),但对于仅在需要时出现的关键错误/消息,您可以而且也许应该能够执行此操作。

更深入地解释了该技术:

  • 当用户尝试重新定位窗口时触发 Configure 事件
  • 调用序列surpress_move 并检查事件详细信息以匹配我们正在寻找的特定案例:
    1. 第一个条件是调用的小部件不是根窗口的子窗口,它必须是根窗口
    2. x 和 y 细节与我们指定的不同。
    3. 我们将 overrideredirect 标志设置为 true,这会导致未经修饰的窗口(没有标题栏),因此没有移动,因为操作系统窗口管理器不再管理移动。
    4. 我们将窗口重新定位回我们想要的位置并再次装饰窗口。

这是代码:

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()

如果你想使用 tkinters 锚常量,你可以这样做:

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()

【讨论】:

  • 好的,感谢您花时间回答我,这个解决方案可能对我有用,但我不认为我会使用它。关键是我试图获得一个永久窗口,该窗口使用数据库值进行更新并且可以被用户读取,但 tkinter 不允许永久更新窗口。唯一适用于我的情况的函数是“after()”和另一个“after()”,但是这个函数在固定数量的这个原因之后崩溃了,因为“函数中的函数中的函数”限制是 992。
  • @thalback 请在 s 时间问一个问题。我提供的答案解决了您的问题,不仅针对您,将来也应该对其他人有所帮助。您应该考虑接受这个答案,并根据您更新的问题提出一个新答案。你可以在这里通知我,我可以看一下。
  • 是的,你是对的抱歉,我会创建另一个话题
猜你喜欢
  • 1970-01-01
  • 2016-10-21
  • 2011-03-22
  • 1970-01-01
  • 2021-09-16
  • 1970-01-01
  • 2017-11-15
  • 2020-11-07
  • 1970-01-01
相关资源
最近更新 更多