在tkinter窗口中禁用退出(或[X]) [英] Disable Exit (or [ X ]) in tkinter Window

查看:195
本文介绍了在tkinter窗口中禁用退出(或[X])的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之所以发布此信息,是因为我自己一直在努力寻找关于该问题的明确答案. .

I am posting this because I myself have struggled with finding a clear answer on this problem . . .

在尝试为我的程序创建进度条时,我发现使用tkinter很难.要完成创建进度条而不会遇到可怕的主循环",请

In search of trying to create a progress bar for my program, I find that it is difficult to do using tkinter. To accomplish creating a progress bar without running into the dreaded "mainloop", I opted to make a class out of the progress bar using threads. Through lots of trial an error, I found that there is not much that can be customized due to the use of multithreading (tkinter likes being in the main thread). Here are two options I have tried, followed by a third that best fits my needs:

给出以下代码:

import tkinter as tk
import tkinter.ttk as ttk
import threading


class ProgressbarApp(threading.Thread):

    def __init__(self, max_value: int):
        self.max_value = max_value

        self.root = None
        self.pb = None

        threading.Thread.__init__(self)
        self.lock = threading.Lock()    # (1)
        self.lock.acquire()             # (2)
        self.start()

        # (1) Makes sure progressbar is fully loaded before executing anything
        with self.lock:
            return

    def close(self):
        self.root.quit()

    def run(self):

        self.root = tk.Tk()
        self.root.protocol("WM_DELETE_WINDOW", self.__callback)

        self.pb = ttk.Progressbar(self.root, orient='horizontal', length=400, mode='determinate')
        self.pb['value'] = 0
        self.pb['maximum'] = self.max_value
        self.pb.pack()

        self.lock.release()             # (2) Will release lock when finished
        self.root.mainloop()

    def update(self, value: int):
        self.pb['value'] = value

    @staticmethod
    def __callback():
        return

if __name__ == '__main__':
    interval = 100000
    my_pb = ProgressbarApp(interval)

    for i in range(interval):
        my_pb.update(i)

    my_pb.close()

    # Other stuff goes on . . .

哪里

self.root.protocol("WM_DELETE_WINDOW", self.__callback)

防止关闭窗口.但是,如果要按住退出"或[X]按钮,则进度条将冻结,直到用户释放该按钮. (__callback函数不断被调用,以防止其他任务完成).

Prevents the window from being closed. However, if the Exit, or [ X ], button were to be held down, the progress bar would freeze until the user releases the button. (The __callback function is constantly being called, preventing other tasks from being completed).

给出以下代码:

import tkinter as tk
import tkinter.ttk as ttk
import threading


class ProgressbarApp(threading.Thread):

    def __init__(self, max_value: int):
        self.max_value = max_value

        self.root = None
        self.pb = None

        threading.Thread.__init__(self)
        self.lock = threading.Lock()    # (1)
        self.lock.acquire()             # (2)
        self.start()

        # (1) Makes sure progressbar is fully loaded before executing anything
        with self.lock:
            return

    def close(self):
        self.root.quit()

    def run(self):

        self.root = tk.Tk()
        self.root.overrideredirect(True)

        self.pb = ttk.Progressbar(self.root, orient='horizontal', length=400, mode='determinate')
        self.pb['value'] = 0
        self.pb['maximum'] = self.max_value
        self.pb.pack()

        self.lock.release()             # (2) Will release lock when finished
        self.root.mainloop()

    def update(self, value: int):
        self.pb['value'] = value

if __name__ == '__main__':
    interval = 100000
    my_pb = ProgressbarApp(interval)

    for i in range(interval):
        my_pb.update(i)

    my_pb.close()

    # Other stuff goes on . . .

哪里

self.root.overrideredirect(True)

清除所有的tkinters窗口选项.但是,进度条不仅位于奇怪的位置,而且还会遮挡用户窗口.进度条应该对用户友好.

Clears all of tkinters window options. However, the progress bar is not only in an odd location, but it also obscures the users window. The progress bar should user friendly.

给出以下代码:

import tkinter as tk
import tkinter.ttk as ttk
import threading


class ProgressbarApp(threading.Thread):

    def __init__(self, max_value: int):
        self.max_value = max_value

        self.root = None
        self.pb = None

        threading.Thread.__init__(self)
        self.lock = threading.Lock()    # (1)
        self.lock.acquire()             # (2)
        self.start()

        # (1) Makes sure progressbar is fully loaded before executing anything
        with self.lock:
            return

    def close(self):
        self.root.quit()

    def run(self):

        self.root = tk.Tk()
        self.root.attributes('-disabled', True)

        self.pb = ttk.Progressbar(self.root, orient='horizontal', length=400, mode='determinate')
        self.pb['value'] = 0
        self.pb['maximum'] = self.max_value
        self.pb.pack()

        self.lock.release()             # (2) Will release lock when finished
        self.root.mainloop()

    def update(self, value: int):
        self.pb['value'] = value

if __name__ == '__main__':
    interval = 100000
    my_pb = ProgressbarApp(interval)

    for i in range(interval):
        my_pb.update(i)

    my_pb.close()

    # Other stuff goes on . . .

哪里

self.root.attributes('-disabled', True)

防止任何用户与窗口的交互.这最适合我对该程序的需求,因为它可以防止窗口关闭并且外观仍然很好. (我唯一的小问题是用户无法再最小化进度条或将其移走.)

Prevents any user interaction with the window. This has best suited my needs for this program as it prevents the window from closing and still has a nice appearance to it. (My only minor issue with it is that the user can no longer minimize the progress bar or move it around).

如果有更好的解决方案,我很乐意看到它们.希望这对某人有所帮助.

If there are any better solutions, I would love to see them. Hopefully, this has helped someone.

推荐答案

您可以创建一个仅使用pass不执行任何操作的函数.

You can create a function that just uses pass to do nothing.

看看下面的内容:

import tkinter as tk


root=tk.Tk()

def close_program():
    root.destroy()

def disable_event():
    pass

btn = tk.Button(root, text = "Click me to close", command = close_program)
btn.pack()

root.protocol("WM_DELETE_WINDOW", disable_event)

root.mainloop()

您还可以将工具栏与root.overrideredirect(True)一起删除,这将阻止用户使用任何工具栏.离开root.protocol("WM_DELETE_WINDOW", disable_event)也会阻止使用ALT + F4.

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 tk


root=tk.Tk()
root.geometry("400x400")
root.overrideredirect(True)

def close_program():
    root.destroy()

def disable_event():
    pass

btn = tk.Button(root, text = "Click me to close", command = close_program)
btn.pack()

root.protocol("WM_DELETE_WINDOW", disable_event)

root.mainloop()

这篇关于在tkinter窗口中禁用退出(或[X])的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆