英文:
How to determine if tkinter Toplevel widget exists.?
问题
Sure, here is the translated code:
我有一个需要在创建 `Toplevel` 窗口之前销毁它(如果已经存在)的需求。我已经研究过这个问题,无论是在这里还是其他地方,每一个回答都建议使用 `winfo_exists` 方法;然而,下面的代码演示了它不起作用。它会出现错误:对象没有属性 'toplevel'。
我可以使用粗暴的 try:/except: 方法来销毁窗口,但肯定有更好的方法。
顺便说一下:我在运行 Python 3.11.1 的 Windows 10 上。
```python
# does_widget_exist.py
import tkinter as tk
class TL_GUI:
def __init__(self):
self.root = tk.Tk()
self.root.geometry('300x100')
self.root.title('Tkinter Test')
button0 = tk.Button(self.root, text='创建 Toplevel', command=self.makeToplevel)
button0.pack(pady=20)
self.toplevel = None
self.root.mainloop()
def makeToplevel(self):
if self.toplevel and self.toplevel.winfo_exists():
self.toplevel.destroy()
self.toplevel = tk.Toplevel(self.root)
self.toplevel.geometry('500x100')
self.toplevel.title('我是一个 TopLevel')
text0 = tk.Label(self.toplevel, text='你好,世界', height=1, width=25, borderwidth=5)
text0.pack()
if __name__ == '__main__':
TL_GUI()
I hope this helps. If you have any other questions or need further assistance, please let me know.
英文:
I have a need to destroy a Toplevel
widget if it already exists before creating it. I've researched this and every response I can find here and elsewhere suggest using winfo_exists
; however, the following code demonstrates that doesn't work. It fails with the error: object has no attribute 'toplevel'
I can use a brute force try:/except: to destroy the widget, but surely there's a better way.
BTW: I am on Windows 10 running Python 3.11.1
# does_widger_exists.py
import tkinter as tk
class TL_GUI:
def __init__(self):
self.root = tk.Tk()
self.root.geometry('300x100')
self.root.title('Tkinter Test')
button0 = tk.Button(self.root,text='Create Toplevel',command=self.makeToplevel).pack(pady=20)
self.root.mainloop()
def makeToplevel(self):
if tk.Toplevel.winfo_exists(self.toplevel):
self.toplevel.destroy()
self.toplevel = tk.Toplevel(self.root)
self.toplevel.geometry('500x100')
self.toplevel.title('I am a TopLevel')
text0 = tk.Label(self.toplevel,text='Hello World',height=1,width=25,borderwidth=5).pack()
if __name__ == '__main__':
TL_GUI()
答案1
得分: 1
你需要在你的__init__
方法中初始化self.toplevel
为某个值,这样第一次调用makeToplevel
时,当进入条件语句时不会失败;如代码所示,当首次运行检查时,self.toplevel
不存在。有了这个修复,后续对makeToplevel
的调用将按预期工作。
def __init__(self):
self.root = tk.Tk()
self.root.geometry('300x100')
self.root.title('Tkinter Test')
self.toplevel = None # 初始化这个实例变量
button0 = tk.Button(
self.root,
text='Create Toplevel',
command=self.makeToplevel
).pack(pady=20)
self.root.mainloop()
你还应该按以下方式更新if
语句检查的条件:
def makeToplevel(self):
if self.toplevel and self.toplevel.winfo_exists(): # 做这个更改
self.toplevel.destroy()
self.toplevel = tk.Toplevel(self.root)
self.toplevel.geometry('500x100')
self.toplevel.title('I am a TopLevel')
text0 = tk.Label(
self.toplevel,
text='Hello World',
height=1,
width=25,
borderwidth=5
).pack()
另外,最后要注意一点:像你在button0
和text0
上使用的pack()
会在不小心的情况下引发问题!如代码所示,button0
和text0
都将始终评估为None
,因为这是pack()
返回的值。如果你想在其他地方引用这些小部件,应该将它们分开pack()
到另一行,例如:
button0 = tk.Button(...) # 现在 'button0' 等于 Button 对象,而不是 None
button0.pack(...)
text0 = tk.Label(...) # 现在 'text0' 等于 Label 对象,而不是 None
text0.pack(...)
英文:
You'll need to initialize self.toplevel
to some value in your __init__
method so the first call to makeToplevel
doesn't fail when it gets to the conditional; as written, self.toplevel
doesn't exist when the check is first run. With this fix, subsequent calls to makeToplevel
will work as expected
def __init__(self):
self.root = tk.Tk()
self.root.geometry('300x100')
self.root.title('Tkinter Test')
self.toplevel = None # initialize this instance variable
button0 = tk.Button(
self.root,
text='Create Toplevel',
command=self.makeToplevel
).pack(pady=20)
self.root.mainloop()
You should also update the condition checked by the if
statement as follows:
def makeToplevel(self):
if self.toplevel and self.toplevel.winfo_exists(): # make this change
self.toplevel.destroy()
self.toplevel = tk.Toplevel(self.root)
self.toplevel.geometry('500x100')
self.toplevel.title('I am a TopLevel')
text0 = tk.Label(
self.toplevel,
text='Hello World',
height=1,
width=25,
borderwidth=5
).pack()
Oh, and one final note: using pack()
like you are on button0
and text0
can cause trouble if you're not careful! As written, button0
and text0
will both always evaluate to None
since that's the value returned by pack()
. If you want to refer to these widgets anywhere else, you should pack()
them on a separate line, e.g.:
button0 = tk.Button(...) # now 'button0' is equal to the Button object, not None
button0.pack(...)
text0 = tk.Label(...) # now 'text0' is equal to the Label object, not None
text0.pack(...)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论