Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I anchor a Tkinter window in my screen (unmovable window)

Tags:

python

tkinter

Im trying to open a tkinter at a specific position and it would be better if it is unmovable. I search on documentation and other and doesnt find anything about that. The best way would be a top side or a bottom side that is fixed at one position x, y and i can resize my window if I want.

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

ws.after(1000, my_functions())
like image 834
thalback Avatar asked Jan 23 '26 03:01

thalback


1 Answers

Under Windows I prefer to disable the window when the user tries to reposition the window, but apparently this is not a cross platform option. Another option, is to use the overrideredirect flag to abort the movement. Just to reposition the window to your desired location ends in flickering all over the screen. With overrideredirect you still experience a blinking but at the same location and it gives me the feel of trying to access a disabled window on MS-Windows where they blink the window.

Be aware, that this code should be used in edge cases like a modal window. It is generally experienced as annoying(!) but for a critical Error/Messages that comes when needed ONLY, you could and maybe should be able to do this.

The technique explained in little more depth:

  • The Configure event is triggered when the user try to relocate the window
  • The sequence surpress_move is called and checks the event details to match the specific case we are looking for:
    1. First Condition the widget that calls is not a child of root, it hast to be the root window
    2. The x and y detail differ from our specified ones.
  • We set the overrideredirect flag to true which results in an undecorated window (no titlebar) and therefore no movement, cause the movement isn't managed anymore, by the operating systems window manager.
  • We relocate our Window back to our desired location and decorate the Window again.

Here is the code:

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

If you want to work with tkinters anchor constants, you could do something like:

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()
like image 75
Thingamabobs Avatar answered Jan 24 '26 17:01

Thingamabobs