Tkinter: windows without title bar but resizable

Dick Wong picture Dick Wong · Mar 15, 2014 · Viewed 9.4k times · Source

What I know is if I want to create a window without title bar, I can write

    root = Tk()
    ........
    root.overrideredirect(1)

But I would also like the window to be resizable. Is there any solution?

(FYI: I am working on Windows machine, although I am not sure if it really matters. It will be perfect if there is OS-independent solution, but I am happy if there is at least a solution for Windows first.)

Answer

Bryan Oakley picture Bryan Oakley · Mar 15, 2014

The problem is, the window is resizable, but when you turn on overrideredirect you lose any sort of header or edge that you can grab in order to resize the window. The only solution is to implement resizing yourself. You can add your own borders, or add mouse bindings that work when the mouse is near an edge.

This answer shows how to move such a window: Python/Tkinter: Mouse drag a window without borders, eg. overridedirect(1)

Here's a short example that illustrates resizing. It has only barely been tested on OSX but should work on any platform. It uses python2, though it should work with python3 just by changing the import statements.

import Tkinter as tk
import ttk

class Example(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.floater = FloatingWindow(self)

class FloatingWindow(tk.Toplevel):
    def __init__(self, *args, **kwargs):
        tk.Toplevel.__init__(self, *args, **kwargs)
        self.overrideredirect(True)
        self.wm_geometry("400x400")

        self.label = tk.Label(self, text="Grab the lower-right corner to resize")
        self.label.pack(side="top", fill="both", expand=True)

        self.grip = ttk.Sizegrip(self)
        self.grip.place(relx=1.0, rely=1.0, anchor="se")
        self.grip.lift(self.label)
        self.grip.bind("<B1-Motion>", self.OnMotion)


    def OnMotion(self, event):
        x1 = self.winfo_pointerx()
        y1 = self.winfo_pointery()
        x0 = self.winfo_rootx()
        y0 = self.winfo_rooty()
        self.geometry("%sx%s" % ((x1-x0),(y1-y0)))
        return

app=Example()
app.mainloop()