Disable Exit (or [ X ]) in tkinter Window
You can create a function that just uses pass
to do nothing.
Take a look at the below:
import tkinter as tkroot=tk.Tk()def close_program(): root.destroy()def disable_event(): passbtn = tk.Button(root, text = "Click me to close", command = close_program)btn.pack()root.protocol("WM_DELETE_WINDOW", disable_event)root.mainloop()
You could also remove the toolbar all together with root.overrideredirect(True)
that will prevent the user from using any of the toolbar. leaving root.protocol("WM_DELETE_WINDOW", disable_event)
will also prevent the use of ALT + F4
.
import tkinter as tkroot=tk.Tk()root.geometry("400x400")root.overrideredirect(True)def close_program(): root.destroy()def disable_event(): passbtn = tk.Button(root, text = "Click me to close", command = close_program)btn.pack()root.protocol("WM_DELETE_WINDOW", disable_event)root.mainloop()
another way to achieve this on windows:
#!python3import tkinter as tkfrom tkinter import ttkimport threading, timeimport tkinter as tkfrom ctypes import windll, wintypesGWL_STYLE = -16WS_CHILD = 0x40000000WS_SYSMENU = 0x00080000SWP_FRAMECHANGED = 0x0020SWP_NOACTIVATE = 0x0010SWP_NOMOVE = 0x0002SWP_NOSIZE = 0x0001# write short names for functions and specify argument and return typesGetWindowLong = windll.user32.GetWindowLongWGetWindowLong.restype = wintypes.ULONGGetWindowLong.argtpes = (wintypes.HWND, wintypes.INT)SetWindowLong = windll.user32.SetWindowLongWSetWindowLong.restype = wintypes.ULONGSetWindowLong.argtpes = (wintypes.HWND, wintypes.INT, wintypes.ULONG)SetWindowPos = windll.user32.SetWindowPosclass App(tk.Tk): def __init__(self): tk.Tk.__init__(self) self.pb = ttk.Progressbar(self, orient="horizontal", length=400, mode="determinate", maximum=100) self.pb.pack() tk.Button(self, text="Remove buttons", command=self.remove_buttons).pack() tk.Button(self, text="Add buttons", command=self.add_buttons).pack() def start(self): self.t = threading.Thread(target=self.loop) self.t.start() def loop(self): while True: for num in range(0, 100): self.pb['value']=num time.sleep(0.1) def _get_hwnd(self): w_id = self.winfo_id() # gets handle style = GetWindowLong(w_id, GWL_STYLE) # get existing style newstyle = style & ~WS_CHILD # remove child style res = SetWindowLong(w_id, GWL_STYLE, newstyle) # set new style res = SetWindowPos(w_id, 0, 0,0,0,0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE) hwnd = int(self.wm_frame(), 16) # find handle of parent res = SetWindowLong(w_id, GWL_STYLE, style) # set back to old style res = SetWindowPos(w_id, 0, 0,0,0,0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE) return hwnd # return parents handle def remove_buttons(self): hwnd = self._get_hwnd() style = GetWindowLong(hwnd, GWL_STYLE) # get existing style style = style & ~WS_SYSMENU res = SetWindowLong(hwnd, GWL_STYLE, style) res = SetWindowPos(hwnd, 0, 0,0,0,0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE) def add_buttons(self): hwnd = self._get_hwnd() style = GetWindowLong(hwnd, GWL_STYLE) # get existing style style = style | WS_SYSMENU res = SetWindowLong(hwnd, GWL_STYLE, style) res = SetWindowPos(hwnd, 0, 0,0,0,0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE)if __name__ == "__main__": app = App() app.start() app.mainloop()