在单独的函数中删除 Tkinter 对象(在函数中创建)
Removing Tkinter Objects (created in a function) in a separate function
我需要能够清除所有对象(带有函数)的 tkinter window,然后使用函数再次创建对象。但是,我无法使用第二个函数访问用第一个函数创建的对象。我在下面重现了我的问题。
import tkinter
window = tkinter.Tk()
def create():
test = tkinter.Button(window, text="Example", command=delete)
test.place(x=75, y=100)
def delete():
test.place_forget()
create()
window.mainloop()
这个returns错误-NameError: name 'test' is not defined
好吧,如果您使用两个不同的函数,您将需要 global
个变量:
import tkinter
window = tkinter.Tk()
test = None
def create():
global test
test = tkinter.Button(window, text="Example", command=delete)
test.place(x=75, y=100)
def delete():
global test
test.destroy() # or place_forget if you want
window.after(5000, create) # button reappears after 5 seconds
create()
window.mainloop()
您的 delete
函数无法破坏按钮,因为它仅在 create
函数中定义。解决方法是创建一个全局变量,两者都可以访问。
下面是使用面向对象结构的代码外观的快速示例:
import tkinter as tk
class MyApp: # No need to inherit 'object' in Python 3
def __init__(self, root):
self.root = root
def create_button(self):
self.test_button = tk.Button(self.root,
text="Example",
command=self.delete_button)
self.test_button.place(x=75, y=100)
def delete_button(self):
self.test_button.place_forget()
def run(self):
self.create_button()
self.root.mainloop()
if __name__=='__main__':
root = tk.Tk()
app = MyApp(root)
app.run()
您创建一个 MyApp
对象,该对象 'owns' 按钮,并具有明确作用于它所拥有的事物的方法。 MyApp
对象的任何方法都有对各种小部件的引用,通过自动发送的 self
参数。
这比您以前的代码多得多,老实说,对于您的代码现在所做的事情,这是一种矫枉过正。 Malik 使用 global
的解决方案可能没问题。但是,如果您想添加更多小部件,将它们分层,让它们以更复杂的方式进行交互等,那么使用 global
可能会引入难以发现的错误,并使您难以理解到底是什么进行中。
我见过的任何对 Tkinter 的重要使用都使用了类似于上述示例的面向对象的风格。
顺便说一句,我不会创建 delete
函数 - 在创建按钮后使用 .config
方法设置命令会更好:
def create_button(self):
self.test_button = tk.Button(self.root, text="Example")
self.test_button.config(command=self.test_button.place_forget)
self.test_button.place(x=75, y=100)
使用 .config
允许您设置命令,这些命令是您刚创建的按钮的方法,当您将命令设置为按钮实例化的一部分时,您不能这样做。
我需要能够清除所有对象(带有函数)的 tkinter window,然后使用函数再次创建对象。但是,我无法使用第二个函数访问用第一个函数创建的对象。我在下面重现了我的问题。
import tkinter
window = tkinter.Tk()
def create():
test = tkinter.Button(window, text="Example", command=delete)
test.place(x=75, y=100)
def delete():
test.place_forget()
create()
window.mainloop()
这个returns错误-NameError: name 'test' is not defined
好吧,如果您使用两个不同的函数,您将需要 global
个变量:
import tkinter
window = tkinter.Tk()
test = None
def create():
global test
test = tkinter.Button(window, text="Example", command=delete)
test.place(x=75, y=100)
def delete():
global test
test.destroy() # or place_forget if you want
window.after(5000, create) # button reappears after 5 seconds
create()
window.mainloop()
您的 delete
函数无法破坏按钮,因为它仅在 create
函数中定义。解决方法是创建一个全局变量,两者都可以访问。
下面是使用面向对象结构的代码外观的快速示例:
import tkinter as tk
class MyApp: # No need to inherit 'object' in Python 3
def __init__(self, root):
self.root = root
def create_button(self):
self.test_button = tk.Button(self.root,
text="Example",
command=self.delete_button)
self.test_button.place(x=75, y=100)
def delete_button(self):
self.test_button.place_forget()
def run(self):
self.create_button()
self.root.mainloop()
if __name__=='__main__':
root = tk.Tk()
app = MyApp(root)
app.run()
您创建一个 MyApp
对象,该对象 'owns' 按钮,并具有明确作用于它所拥有的事物的方法。 MyApp
对象的任何方法都有对各种小部件的引用,通过自动发送的 self
参数。
这比您以前的代码多得多,老实说,对于您的代码现在所做的事情,这是一种矫枉过正。 Malik 使用 global
的解决方案可能没问题。但是,如果您想添加更多小部件,将它们分层,让它们以更复杂的方式进行交互等,那么使用 global
可能会引入难以发现的错误,并使您难以理解到底是什么进行中。
我见过的任何对 Tkinter 的重要使用都使用了类似于上述示例的面向对象的风格。
顺便说一句,我不会创建 delete
函数 - 在创建按钮后使用 .config
方法设置命令会更好:
def create_button(self):
self.test_button = tk.Button(self.root, text="Example")
self.test_button.config(command=self.test_button.place_forget)
self.test_button.place(x=75, y=100)
使用 .config
允许您设置命令,这些命令是您刚创建的按钮的方法,当您将命令设置为按钮实例化的一部分时,您不能这样做。