Python 3 Tkinter Borderless fullscreen application

7.3k views Asked by At

I have been having a problem whilst creating a Python 3 tkinter application. I am currently developing using a Mac OSX system, but I normally use a Windows OS system.

I would like the application to occupy the entire screen without the Window Manager's titlebar and frame being around the application, often referred to a Fullscreen Borderless Window in gaming.

I have tried using root.attributes("-fullscreen", True) with root.overrideredirect(True) and root.wm_attributes("-topmost", 1). However the inclusion of the root.overrideredirect(True) line doesn't allow it to go proper fullscreen; it still shows the Mac Dock and Taskbar, and it also breaks my keystroke bindings in the application. Without the root.overrideredirect(True) line, the application does go into full screen mode (hiding the dock and the task bar), but the window does not fill the entire screen; it leaves a gap at the bottom, and it also retains the window manager's title bar and frame/border.

Here is an example of my code:

import tkinter as tk

class App(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent)

        self.parent = parent

        self.initUI()

    def initUI(self):

        self.parent.title("Fullscreen Application")

        self.pack(fill="both", expand=True, side="top")

        self.parent.wm_state("zoomed")

        self.parent.bind("<F11>", self.fullscreen_toggle)
        self.parent.bind("<Escape>", self.fullscreen_cancel)

        self.fullscreen_toggle()

        self.label = tk.Label(self, text="Fullscreen", font=("default",120), fg="black")
        self.label.pack(side="top", fill="both", expand=True)

    def fullscreen_toggle(self, event="none"):

        self.parent.focus_set()
        self.parent.overrideredirect(True)

        self.parent.attributes("-fullscreen", True)
        self.parent.wm_attributes("-topmost", 1)

    def fullscreen_cancel(self, event="none"):

        self.parent.overrideredirect(False)
        self.parent.attributes("-fullscreen", False)
        self.parent.wm_attributes("-topmost", 0)

        self.centerWindow()

    def centerWindow(self):

        sw = self.parent.winfo_screenwidth()
        sh = self.parent.winfo_screenheight()

        w = sw*0.7
        h = sh*0.7

        x = (sw-w)/2
        y = (sh-h)/2

        self.parent.geometry("%dx%d+%d+%d" % (w, h, x, y))

if __name__ == "__main__":
    root = tk.Tk()
    App(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

I hope that someone is able to help! Thank you!

EDIT: I have just tested this on my Windows computer. Without the self.parent.overrideredirect(True), it creates the app and works perfectly as desired (fullscreen without window manager border or title bar). This must just be an OSX problem.

2

There are 2 answers

1
R4PH43L On

To fix your OS-X Problem i will provide a solution that fixes a similar problem for me. (Had some Issues using fullscreen in between Linux and Windows)

You wanted to get rid of the Window Managers Bar? Take a look at the docs it states an option that removes the window managers items by using -toolwindow option.

Concerning the size of your Application here is what helped me using linux - a "manual zoom":

class MyClass(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.overrideredirect(True) # depending on your needs
        self.attributes("-toolwindow", 1) # this line removes the window managers bar

        try:                                   # Automatic zoom if possible
            self.wm_state("zoomed")
            print("Using automatic zoom")
        except tk.TclError:                    # Manual zoom
            # Bad Argument Error is a TclError
            print("Using manual zoom")

            # get the screen dimensions
            width = self.winfo_screenwidth()
            height = self.winfo_screenheight()

            # build a geometry string. 
            # form: width x height + x_offset + y_offset
            geom_string = "%dx%d+0+0" % (width, height)
            self.wm_geometry(geom_string)

Please note that I am not using an unconfigured tk.Tk() - Instance here - my class is the tk.Tk() - Instance. So I do not need to overwrite the parent but only "myself" speaking of the POV of the class.

1
Gumboy On
#!/usr/bin/python
import Tkinter as tk

class App(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent)

        self.parent = parent

        self.initUI()

    def initUI(self):

        self.parent.title("Fullscreen Application")

        self.pack(fill="both", expand=True, side="top")

        self.parent.wm_state("zoomed")

        self.parent.bind("<F11>", self.fullscreen_toggle)
        self.parent.bind("<Escape>", self.fullscreen_cancel)

        self.fullscreen_toggle()

        self.label = tk.Label(self, text="Fullscreen", font=("default",120), fg="black")
        self.label.pack(side="top", fill="both", expand=True)

    def fullscreen_toggle(self, event="none"):

        self.parent.focus_set()
        self.parent.overrideredirect(True)
        self.parent.overrideredirect(False) #added for a toggle effect, not fully sure why it's like this on Mac OS
        self.parent.attributes("-fullscreen", True)
        self.parent.wm_attributes("-topmost", 1)

    def fullscreen_cancel(self, event="none"):

        self.parent.overrideredirect(False)
        self.parent.attributes("-fullscreen", False)
        self.parent.wm_attributes("-topmost", 0)

        self.centerWindow()

    def centerWindow(self):

        sw = self.parent.winfo_screenwidth()
        sh = self.parent.winfo_screenheight()

        w = sw*0.7
        h = sh*0.7

        x = (sw-w)/2
        y = (sh-h)/2

        self.parent.geometry("%dx%d+%d+%d" % (w, h, x, y))

if __name__ == "__main__":
    root = tk.Tk()
    App(root).pack(side="top", fill="both", expand=True)
    root.mainloop()