我正在使用Tkinter创建一个程序,它将创建一个事件列表。我用了一堂课来制作一个活动。如果单击添加事件按钮(显示第二个脚本),它将创建该类的新实例,从而延长列表。但是,我还希望能够从列表中删除事件。我正在尝试将删除按钮附加到每个类,当单击时,将删除该类。这是我的类脚本(classes.py
)中的代码:
from Tkinter import *
class agendaEvent:
def __init__(self, master):
self.frame = Frame(master, padx=10, pady=10)
self.frame.pack(side=TOP)
self.name = Entry(self.frame)
self.name.grid(row=1, column=0)
self.time = Entry(self.frame, width=10)
self.time.grid(row=1, column=1, padx=5)
self.label1 = Label(self.frame, text="Event Name")
self.label1.grid(row=0, column=0)
self.label2 = Label(self.frame, text="Minutes")
self.label2.grid(row=0, column=1)
self.remove = Button(self.frame, text="Remove", command=agendaEvent.remove)
self.remove.grid(row=1, column=3)
def remove(agendaEvent):
del agendaEvent
当我按下删除按钮时,我收到错误
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1532, in __call__
return self.func(*args)
TypeError: unbound method remove() must be called with agendaEvent instance as first argument (got nothing instead)
如何调用agendaEvent
的实例?或者有更好的方法来解决这个问题吗?这是主脚本(main.py
)的代码:
from Tkinter import *
import classes
def addEvent():
classes.agendaEvent(root)
root = Tk()
addEventButton = Button(root, text="Add Event", command=addEvent)
addEventButton.pack(side=BOTTOM)
root.mainloop()
答案 0 :(得分:0)
您可以使用.destroy()删除标签和其他小部件(不确定全部)。如果以某种方式存储类的实例,您可以忘记或销毁它们,但如果实例只是一个实例,那么我就不会看到您的问题(阅读,我无法帮助您)。如果您想学习如何使用Tkinter构建GUI,您应该在youtube上查看有关该主题的sentdex视频。
这就是我使用按钮的方式制作tkinter小部件,就像我想你要做的那样:
我使用字典来保持我的标签和其他小部件的顺序,例如通过使用计数器变量作为键。
示例:
from tkinter import *
class MyEvent("something tkinter"):
def __init__(self, parent):
"here you need some tkinter code to make a frame or something to put your widgets in"
self.mycounter = 0
self.myEventLabel = {}
addButton = Button(parent, text="add event", command=addEvent).pack()
destroyButton = Button(parent, text="remove last event", command=removeEvent).pack()
def addEvent(self):
self.myEventLabel[self.mycounter] = Label("Here goes the options you want)
self.mycounter+=1
def removeEvent(self):
self.mycounter-=1
self.myEventLabel[self.mycounter].destroy()
希望这有所帮助,如果我错过了重点,那么在我的辩护中,我不是程序员,只是需要使用编程作为达到目的的手段。同样,Sentdex的视频涵盖了很多tkinter,请查看它们。
答案 1 :(得分:0)
您必须保存类实例才能将其删除。下面,addEvent()已被更改为从调用类中捕获返回,并且该实例附加到按钮,因此按钮知道要销毁哪个实例。如果所有代码都包含在类中,但是我遵循您在上面发布的代码,这可能只是一个简单的例子。
from Tkinter import *
from functools import partial
class agendaEvent:
def __init__(self, master):
self.frame = Frame(master, padx=10, pady=10)
self.frame.grid()
self.name = Entry(self.frame)
self.name.grid(row=1, column=0)
self.time = Entry(self.frame, width=10)
self.time.grid(row=1, column=1, padx=5)
self.label1 = Label(self.frame, text="Event Name")
self.label1.grid(row=0, column=0)
self.label2 = Label(self.frame, text="Minutes")
self.label2.grid(row=0, column=1)
def addEvent(master):
this_instance=agendaEvent(master)
## add the button to the frame created by this function call
## and not to the root, so it also is destroyed
rem = Button(this_instance.frame, text="Remove", bg="lightblue",
command=partial(remove_class, this_instance))
rem.grid(row=6, column=0)
def remove_class(instance):
## destroys the frame created by the instance
## i.e. self.frame in agendaEvent
instance.frame.destroy()
instance="" ## reassigns "instance" so the class is garbage collected
root = Tk()
addEventButton = Button(root, text="Add Event", command=partial(addEvent, root))
addEventButton.grid(row=5, column=0)
Button(root, text="Exit", bg="orange", command=root.quit).grid(row=99, column=0)
root.mainloop()
答案 2 :(得分:0)
如下所示更改课程将修复您当前获得的错误。这是因为传递给command
构造函数的Button
关键字参数指定的处理程序总是在没有任何参数的情况下被调用。使用lambda
函数修复它会暴露另一个问题,即您已将Button
实例和要将其关联的方法命名为同一事物 - remove
- 所以我将其重命名为remove_button
。
from Tkinter import *
class agendaEvent:
def __init__(self, master):
self.frame = Frame(master, padx=10, pady=10)
self.frame.pack(side=TOP)
self.name = Entry(self.frame)
self.name.grid(row=1, column=0)
self.time = Entry(self.frame, width=10)
self.time.grid(row=1, column=1, padx=5)
self.label1 = Label(self.frame, text="Event Name")
self.label1.grid(row=0, column=0)
self.label2 = Label(self.frame, text="Minutes")
self.label2.grid(row=0, column=1)
self.remove_button = Button(self.frame, text="Remove",
command=lambda: self.remove())
self.remove_button.grid(row=1, column=3)
def remove(self): # by convention the first argument to a class
del self # method is usually named "self"