在我的一个项目中,我试图在我的根窗口(self)的子 tk.Toplevel 窗口(child1)中检查用户是否从根窗口中创建了 tk.Toplevel 窗口(child2),如果这个窗口(child2)目前出现在用户屏幕上。
如果不是这种情况,新的 tk.Toplevel 窗口应该由根窗口的子窗口 (child1) 创建,而不是由根窗口本身创建。如果它已经由根窗口创建并且当前出现在用户屏幕上,它应该获得 focus() 而不是由“child1”重新初始化。
根窗口被封装在一个名为 App() 的类中,两个“子”窗口都是由根类 App() 中的方法创建的。
如果提供给该方法的参数为 True,我必须以安静模式初始化“child2”。我想那是纠缠不清的错误。问题发生在 Windows 7 64 位上,如果这很重要的话。
我试过这个(例子):
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
top = self.winfo_toplevel()
self.menuBar = tk.Menu(top)
top['menu'] = self.menuBar
self.menuBar.add_command(label='Child1', command=self.__create_child1)
self.menuBar.add_command(label='Child2', command=lambda: self.__create_child2(True))
self.TestLabel = ttk.Label(self, text='Use the buttons from the toplevel menu.')
self.TestLabel.pack()
self.__create_child2(False)
def __create_child1(self):
self.Child1Window = tk.Toplevel(master=self, width=100, height=100)
self.Child1WindowButton = ttk.Button(self.Child1Window, text='Focus Child2 window else create Child2 window', command=self.CheckForChild2)
self.Child1WindowButton.pack()
def __create_child2(self, givenarg):
self.Child2Window = tk.Toplevel(master=self, width=100, height=100)
if givenarg == False:
self.Child2Window.withdraw()
# Init some vars or widgets
self.Child2Window = None
else:
self.Child2Window.TestLabel = ttk.Label(self.Child2Window, text='This is Child 2')
self.Child2Window.TestLabel.pack()
def CheckForChild2(self):
if self.Child2Window:
if self.Child2Window.winfo_exists():
self.Child2Window.focus()
else:
self.__create_child2(True)
else:
self.__create_child2(True)
if __name__ == '__main__':
App().mainloop()
问题来了:我无法检查“child2”是否已经存在。出现错误:_tkinter.TclError: bad window path name
解决方案:
获得正确的“窗口路径名称”的唯一方法是,不是直接在“child2”窗口上调用 winfo_exists() 方法,而是调用“child1”窗口的主窗口并添加相应的属性,然后是您要使用的主窗口。
示例(编辑 CheckForChild2 方法):
def CheckForChild2(self):
if self.Child2Window:
if self.Child1Window.master.Child2Window.winfo_exists():
self.Child1Window.master.Child2Window.focus()
else:
self.__create_child2(True)
else:
self.__create_child2(True)