Unclosable window using tkinter

后端 未结 2 496
北荒
北荒 2021-01-23 00:24

Hey I am making a program that take a picture using my webcam when I type the wrong password. The program will be open and I want it unclosable. I need to know how to make a win

相关标签:
2条回答
  • 2021-01-23 01:00

    Tkinter doesn't have any way to do this directly. But it does have something that may be good enough, or it may be too much overkill: the overrideredirect flag:

    If non-zero, this prevents the window manager from decorating the window. In other words, the window will not have a title or a border, and it cannot be moved or closed via ordinary means.

    That's not quite up-to-date; it may actually have a title or border on some platforms… but it won't be closable.

    This is easy to use: just do root.overrideredirect(True) (or, if you want to do it to a different Toplevel window instead of your root, window.overrideredirect(True)).


    But notice that it can't be moved or closed, not just that it can't be closed. (It also can't be resized, if you want that.)

    So, the only thing you can do is set the flag, but then bind the mouse-button events to handle moving manually. For example, in your window's __init__ method:

    self.overrideredirect(True) # if this is a Toplevel
    #self.parent.overrideredirect(True) # if this is a Frame on root
    
    self.bind('<ButtonPress-1>', self.move_start)
    self.bind('<ButtonRelease-1>', self.move_end)
    self.bind('<B1-Motion>', self.move_move)
    

    And then:

    def move_start(self, event):
        self.startx, self.starty = event.x, event.y
    
    def move_stop(self, event):
        self.move_move(event)
    
    def move_move(self, event):
        x = self.winfo_x() + event.x - self.startx
        y = self.winfo_y() + event.y - self.starty
        self.geometry("+%s+%s" % (x, y))
    

    Obviously, if you want any widgets within the window to accept clicks, you probably don't want to make the whole window a drag area. In fact, you may not want to make the whole window a drag area even if it doesn't have anything to click, because that's not really following Mac or Windows human interface guidelines. You could fake a grip area—a title bar, a border around the window, etc.—just by, e.g., adding a Label pinned to the side(s) you want to grip from and only binding there, or by creating a "child" window inset from the main window that steals the bindings. But this is never going to look like a "native" window.

    If you really need a native window, but with the close box (the X in the top-right corner on Windows, the red dot in the top-left on Mac, etc.) disabled or missing (and, on Windows, with the "close" item on the window menu disabled, and Alt+F4, and so on, and similarly for X11…)… As far as I know, there's no cross-platform way to do that in Tkinter. You will have to write code for each platform that gets at the underlying native window objects and does native window things to them. At that point, you probably want to look at using a more powerful windowing library than Tkinter—e.g., I believe Qt, Gtk+, and wx all have much simpler ways of creating a normal window but with the close box disabled.

    0 讨论(0)
  • 2021-01-23 01:21

    You can try all of the many things @abarnert suggested, but I think the easiest way would be to just ignore the close event.

    From this question:

    Here you have a concrete example:

    import Tkinter as tk
    import tkMessageBox as messagebox
    root = tk.Tk()
    
    def on_closing():
        if messagebox.askokcancel("Quit", "Do you want to quit?"):
            root.destroy()
    
    root.protocol("WM_DELETE_WINDOW", on_closing)
    root.mainloop()
    

    (edited code for Windows)

    So change on_closing() to
    def on_closing(): pass
    and that makes it unclosable. I tried Alt+F4, the close button, closing it from the Windows Taskbar, all to no avail. The only way I was able to kill it was to use Task Manager.

    0 讨论(0)
提交回复
热议问题