【问题标题】:Python Tkinter. Show only one copy of windowPython Tkinter。仅显示一份窗口副本
【发布时间】:2015-03-24 12:46:40
【问题描述】:

我有一个问题。我有在 Tkinter 上编写的程序。

import Tkinter as tk
import ttk


def about_window():
    print(root.child_window)

    if not root.child_window:
        top2 = tk.Toplevel(root)
        top2.title("About")
        top2.resizable(0,0)

        explanation = "This program is my test program"

        ttk.Label(top2,justify=tk.LEFT,text=explanation).pack(padx=5,pady=2)
        ttk.Button(top2,text='OK',width=10,command=top2.destroy).pack(pady=8)


root = tk.Tk()
root.resizable(0,0)

root.child_window = None
#print(root.child_window)

root.style = ttk.Style()
# ('clam', 'alt', 'default', 'classic')
root.style.theme_use("clam")

menu = tk.Menu(root)
root.config(menu=menu)

fm = tk.Menu(menu, tearoff=0)
menu.add_cascade(label="Settings",menu=fm)
fm.add_command(label="Preferances")

hm = tk.Menu(menu, tearoff=0)
menu.add_cascade(label="Help",menu=hm)
hm.add_command(label="About", command=about_window)
hm.add_command(label="Exit",command=root.quit)
#

tk.mainloop()

所以我可以点击“关于”标签并看到窗口:

但是在 Tkinter 中是否可以禁用同一窗口的任何下一次启动?

我已经尝试过 https://stackoverflow.com/a/24886806/2971192 但没有成功。

【问题讨论】:

  • 有两种方法可以做到这一点,您是否希望用户能够在“关于”打开或不打开时与您的主窗口进行交互?
  • Jkdc,你能展示两种方式吗?
  • “没有成功”是什么意思?你有错误吗?尽管有if 声明,您是否获得了多个窗口?一般模式是正确的:第一次创建窗口,然后让它可见。这是一种非常常见的技术。

标签: python tkinter


【解决方案1】:

一种方法是使子窗口瞬态到根,这样在子关闭之前您无法与根交互(这里不需要root.child_window):

import Tkinter as tk
import ttk

def about_window(): 
    top2 = tk.Toplevel(root)
    top2.title("About")
    top2.resizable(0,0)

    explanation = "This program is my test program"

    ttk.Label(top2,justify=tk.LEFT,text=explanation).pack(padx=5,pady=2)
    ttk.Button(top2,text='OK',width=10,command=top2.destroy).pack(pady=8)

    top2.transient(root)
    top2.grab_set()
    root.wait_window(top2)

root = tk.Tk()
root.resizable(0,0)

root.style = ttk.Style()
# ('clam', 'alt', 'default', 'classic')
root.style.theme_use("clam")

menu = tk.Menu(root)
root.config(menu=menu)

fm = tk.Menu(menu, tearoff=0)
menu.add_cascade(label="Settings",menu=fm)
fm.add_command(label="Preferances")

hm = tk.Menu(menu, tearoff=0)
menu.add_cascade(label="Help",menu=hm)
hm.add_command(label="About", command=about_window)
hm.add_command(label="Exit",command=root.quit)
#

tk.mainloop()

【讨论】:

  • afaik transient 更多的是提示 WM 建立子-父关系,因此 WM 不会例如当父级被缩小时,在任务栏中显示关于窗口,或最小化关于窗口。这可能是个好主意,但通过grab_set afaik 完成模式。
【解决方案2】:

使您的关于窗口模式的最简单方法是 afaik 将以下行添加到您的 about_window() 函数:

top2.focus_set()                                                        
top2.grab_set()    

第一行将焦点设置为您的 about 窗口,

第二行禁止任何其他窗口接受事件。

【讨论】:

    【解决方案3】:

    通过使用类来表示您的程序,另一种方法变得容易得多。它本质上归结为对全局(或类实例的范围)变量的需求。在这种情况下,我们使用self.top2,它可以在方法about_window() 的内部和外部访问。

    此方法将允许在子窗口打开时与根窗口进行完全交互。

    import Tkinter as tk
    import ttk
    
    
    class MyProgram():
    
        def __init__(self):
    
            self.top2 = None
            self.root = root = tk.Tk()
            root.resizable(0,0)
    
            root.style = ttk.Style()
            # ('clam', 'alt', 'default', 'classic')
            root.style.theme_use("clam")
    
            menu = tk.Menu(root)
            root.config(menu=menu)
    
            fm = tk.Menu(menu, tearoff=0)
            menu.add_cascade(label="Settings",menu=fm)
            fm.add_command(label="Preferances")
    
            hm = tk.Menu(menu, tearoff=0)
            menu.add_cascade(label="Help",menu=hm)
            hm.add_command(label="About", command=self.about_window)
            hm.add_command(label="Exit",command=root.quit)
    
        def about_window(self):
            try:
                self.top2.focus_set()
                return
            except Exception:
                pass
    
            self.top2 = top2 = tk.Toplevel(self.root)
            top2.title("About")
            top2.resizable(0,0)
    
            explanation = "This program is my test program"
    
            ttk.Label(top2,justify=tk.LEFT,text=explanation).pack(padx=5,pady=2)
            ttk.Button(top2,text='OK',width=10,command=top2.destroy).pack(pady=8)
    
    
    MyProgram()
    tk.mainloop()
    

    【讨论】:

      【解决方案4】:

      状态(newstate=None)

      Returns the window's current state, one of:
      
          'normal': Displayed normally.
      
          'iconic': Iconified with the .iconify() method.
      
          'withdrawn': Hidden; see the .withdraw() method below.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-08
        • 2017-07-11
        • 1970-01-01
        相关资源
        最近更新 更多