【问题标题】:How can I check whether a tkinter window exists?如何检查 tkinter 窗口是否存在?
【发布时间】:2017-09-04 11:49:57
【问题描述】:

我在 python 2.7 中编写了这段代码。在这里,我创建了一个名为 message 的按钮。每当我单击此按钮时,都会创建一个新窗口。现在我想检查一个条件,如果新窗口(单击按钮后出现)存在,则显示一个存在相同类型窗口的弹出窗口。如果没有相同类型的窗口,则应创建新窗口。

from Tkinter import *

def message():
    m_root = Tk()

    entry_value = StringVar()

    m_label = Label(m_root, text="message")
    m_label.pack()

    frame1 = Frame(m_root)
    frame1.pack()
    frame2 = Frame(m_root)
    frame2.pack()

    entry_box = Entry(frame1, width=30, bd=5)
    entry_box.pack()

    button1 = Button(frame2, text="Comment")
    button1.pack(side="left")

    m_root.mainloop()

root = Tk()

root.geometry('150x30+1+1')
root.wm_attributes("-topmost", True)

comment_button = Button(root, text="Comment", command = message, bg="gray", width=10)
comment_button.pack(anchor=CENTER)

root.mainloop()

【问题讨论】:

    标签: python python-2.7 tkinter


    【解决方案1】:

    您可以使用小部件对象的winfo_exists() 方法检查窗口是否存在。

    但是,您不应该在消息函数中再次调用Tk()。相反,我们有Toplevel 用于新的*窗口(即对话框)。顶层有一个所有者,它可以是 Tk 根窗口或其他应用程序窗口。这样窗口管理器将看到正确的窗口层次结构。

    最好将对话框顶层设置为其父级 (dlg.wm_transient(root)) 的瞬态,以便窗口管理器仅显示应用程序根的任务栏图标,而不是它创建的每个对话框。

    编辑

    下面的修改示例展示了如何使用 Toplevel 和 wm_transient 来实现此目的,以及用于制作模态对话框并将新对话框放置在父小部件顶部的抓取。 (这使用了python3,因为这就是我所拥有的)。

    import tkinter as tk
    import tkinter.ttk as ttk
    
    def show_dialog(parent):
        dlg = tk.Toplevel(parent)
        dlg.wm_title("Dialog box")
        dlg.wm_transient(parent)
    
        frame = ttk.Frame(dlg)
        label = ttk.Label(frame, text="Message:")
        entry = ttk.Entry(frame, width=30)
        button = ttk.Button(frame, text="Comment")
    
        label.grid(row=0, column=0, columnspan=2, sticky='NEWS')
        entry.grid(row=1, column=0, sticky='NEWS')
        button.grid(row=1, column=1, sticky='NEWS')
    
        frame.grid_columnconfigure(0, weight=1)
        frame.grid_rowconfigure(2, weight=1)
    
        frame.grid(row=0, column=0, sticky='NEWS')
        dlg.grid_columnconfigure(0, weight=1)
        dlg.grid_rowconfigure(0, weight=1)
    
        entry.focus()
        dlg.grab_set()
        dlg.tk.eval('tk::PlaceWindow {0} widget {1}'.format(dlg, parent))
    
    def main():
        root = tk.Tk()
        root.geometry('320x120')
        root.wm_title("Demo application")
        comment_button = ttk.Button(root, text="Comment", command=lambda: show_dialog(root))
        comment_button.pack(anchor=tk.CENTER)
        root.mainloop()
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

    • 我是 python 新手,所以请您根据您的概念添加更新的代码,我也很困惑在哪里放置我的条件来检查窗口是否存在。 @patthoyts
    • @AnupamYadav 添加了使用 python3 的示例
    • 感谢@patthoyts。它的工作。但是你能告诉我下面这行的意思吗-“dlg.tk.eval('tk::PlaceWindow {0} widget {1}'.format(dlg, parent))”