繁体   English   中英

防止 Tkinter window 弹出一次被调用一次

[英]Prevent Tkinter window to pop up once is called only once

I have a small test Tkinter window with Labels and Entries in a file called "customer.py" I created another file "button_test.py" with a super simple tkinter window with only one button to call "customer.py"

该按钮调用“customer.py”没有问题,但如果我一遍又一遍地再次单击该按钮。不断弹出相同的 window。我可能可以在那里添加一些条件,但我想知道是否有更好的方法防止这种情况发生。我看到它也发生在“Tk TopLevel”上

我感谢你的帮助和时间的同志们。

客户.py

from tkinter import *


class OFFLINE():
    def __init__(self,window):
        self.win = window
        self.win.title("Emails")
        
        frame = LabelFrame(self.win, text = 'CUSTOMER INFORMATION')
        frame.grid(column = 0, row = 0, )    
        
        Label(frame, text = "Case Number").grid(column = 0, row = 1)
        self.Case_box = Entry(frame).grid(column = 1, row = 1)
        
        Label(frame, text = "Customer Name").grid(column = 0, row = 2)
        self.name_box = Entry(frame).grid(column = 1, row = 2)
        
        Label(frame, text = "Phone number").grid(column = 0, row = 3)
        self.phone_box = Entry(frame).grid(column = 1, row = 3)

        Label(frame, text = "Email").grid(column = 0, row =4)
        self.email_box = Entry(frame).grid(column =1, row = 4)
        
        
        
def main():
    root = Tk()
    application = OFFLINE(root)
    root.mainloop()
    
if __name__ == '__main__':
    main()

button_test.py

import customer
from tkinter import *

offline = customer

window = Tk()

button = Button(window, text = "Click Me", command =offline.main)


button.pack()

window.mainloop()

您可以禁用按钮

button['state'] = 'disabled'

然后启用它

button['state'] = 'normal'

或者你可以使用.grab_set()来制作modal window 和第一个 window 不会得到键/鼠标事件。


最少的工作代码

from tkinter import *

def set_disabled():
    button1['state'] = 'disabled'

def set_normal():
    button1['state'] = 'normal'
    
window = Tk()

button1 = Button(window, text = "Click Me", command=set_disabled)
button1.pack()

button2 = Button(window, text = "Next Me", command=set_normal)
button2.pack()

window.mainloop()

编辑:

以第二个 window 为例。

它展示了如何使用Toplevel()而不是第二个Tk()而没有第二个 `mainloop()

import tkinter as tk   # PEP8: `import *` is not preferred

# --- functions ---

def close_window():
    top_window.destroy()
    
    button_open['state'] = 'normal'
    
def open_window():
    global top_window  # to keep value in external variable
    global button_close  # to keep value in external variable
    
    button_open['state'] = 'disabled'

    top_window = tk.Toplevel(window)
    
    label = tk.Label(top_window, text="New Window")
    label.pack()
    
    button_close = tk.Button(top_window, text = "Close", command=close_window)
    button_close.pack()
        
# --- main ---

window = tk.Tk()

button_open = tk.Button(window, text="Open", command=open_window)
button_open.pack()

window.mainloop()

编辑:

使用grab_set()制作 window modal的示例

import tkinter as tk   # PEP8: `import *` is not preferred

# --- functions ---

def open_window():

    top_window = tk.Toplevel(window)
    top_window.grab_set()
    
    label = tk.Label(top_window, text="New Window")
    label.pack()
    
    button_close = tk.Button(top_window, text = "Close", command=top_window.destroy)
    button_close.pack()
        
# --- main ---

window = tk.Tk()

button_open = tk.Button(window, text="Open", command=open_window)
button_open.pack()

window.mainloop()

PEP 8 -- Python 代码的样式指南

您可以使用 class模拟 singleton 功能,如下所示:

客户.py

from tkinter import *

__all__ = ['main']

class OFFLINE():
    ...

class _SingletonWin(Toplevel):
    _instance = None

    def __init__(self, master=None, *args, **kw):
        super().__init__(master, *args, **kw)
        self.form = OFFLINE(self)
        self.protocol("WM_DELETE_WINDOW", self.on_destroy)

    @classmethod
    def on_destroy(cls):
        if cls._instance:
            cls._instance.destroy()
            cls._instance = None

    @classmethod
    def get_instance(cls):
        if cls._instance is None:
            cls._instance = cls()
        return cls._instance

def main():
    return _SingletonWin.get_instance()

然后每当调用main()时,只会显示顶层的一个实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM