我是Python和Tkinter的新手,所以无法弄清楚哪个可能是最简单的事情。有人请检查下面的代码并告诉我如何跟踪子类中定义的radiobutton返回的值并将其传递给父类。编译后我收到以下错误:
AttributeError: Toplevel instance has no attribute 'trace_fun'
我不确定为什么我收到此错误,因为我在子类体中定义了trace_fun
。我已成功跟踪父类中的变量,但在尝试在子类中执行此操作时遇到上述错误。
from Tkinter import *
class Parent(Frame):
classvar = 0
def __init__(self):
Frame.__init__(self)
self.master.title("Parent WIndow")
self.master.geometry("200x100")
self.grid()
self._button = Button(self, text="Create", width=10, command=self.new_window)
self._button.grid(row=0, column=0, sticky=E+W)
def new_window(self):
self.new = Child()
class Child(Parent, Frame):
def __init__(self):
Parent.__init__(self)
new = Frame.__init__(self)
new = Toplevel(self)
new.title("Child Window")
new.grid()
new._var = IntVar()
new._var.set(0)
new._var.trace("w", new.trace_fun)
new._radioButton = Radiobutton(new, text = "Option 1", variable = new._var, value = 1)
new._radioButton.grid(row=0, column=0, sticky=W, padx=10, pady=10)
new._radioButton2 = Radiobutton(new, text = "Option 2", variable = new._var, value = 2)
new._radioButton2.grid(row=1, column=0, sticky=W, padx=10, pady=10)
new._button = Button(new, text = 'Ok', command=new.destroy)
new._button.grid(row=2, column=0, pady=10)
def trace_fun(new, *args):
print new._var.get()
Parent.classvar = new._var.get()
obj = Parent()
def main():
obj.mainloop()
main()
答案 0 :(得分:-1)
您已在此处覆盖了new
变量:
new = Frame.__init__(self)
new = Toplevel(self)
执行这两个语句后,new
等于Toplevel类的实例。
接下来,此代码执行:
new._var.trace("w", new.trace_fun)
,特别是:
new.trace_fun
因此,您有一个Toplevel实例尝试访问名为trace_fun的属性。错误消息告诉您Toplevel类没有任何名为trace_fun的属性。
编辑:
你不能在Toplevel实例上调用trace_fun。你也不能在父实例上调用trace_fun。因此,打印出您的程序副本,然后获得一支笔并圈出所有Toplevel实例的变量;然后圈出作为父实例的所有变量。您不能在任何这些变量上调用trace_fun。或者,圈出作为子实例的所有变量。你可以在这些变量上调用trace_fun。
以下是您可以执行的操作示例:
class Child:
def do_stuff(self): #1) self is an instance of class Child, i.e. the object that is calling this method
self.trace_fun() #2) The Child class defines a method named trace_fun()
#3) Therefore, self can call trace_fun()
x = self.trace_fun #4) ...or you can assign self.trace_fun to a variable
#5) ...or pass self.trace_fun to another function
def trace_fun(self):
print 'hello'
d = Chile()
d.do_stuff()
--output:--
hello
看起来您的两个帧之间没有父/子关系 - 因为子帧不使用从父帧继承的任何内容。所以你可以为你的应用创建两个独立的框架。这是一个例子:
import Tkinter as tk
class EntryFrame(tk.Frame):
classvar = 0
def __init__(self, root):
tk.Frame.__init__(self, root) #Send root as the parent arg to Frame's __init__ method
root.title("Parent Window")
root.geometry("400x200")
tk.Label(self, text="First").grid(row=0)
tk.Label(self, text="Second").grid(row=1)
e1 = tk.Entry(self)
e2 = tk.Entry(self)
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
button = tk.Button(self, text="Create", width=10, command=self.create_new_window)
button.grid(row=2, column=0, sticky=tk.E + tk.W)
self.grid()
def create_new_window(self):
RadioButtonFrame()
class RadioButtonFrame(tk.Frame):
def __init__(self):
new_top_level = tk.Toplevel()
tk.Frame.__init__(self, new_top_level) #Send new_top_level as the parent arg to Frame's __init__ method
new_top_level.title("Radio Button Window")
new_top_level.geometry('400x300+0+300') # "width x height + x + y"
self.int_var = int_var = tk.IntVar()
int_var.trace("w", self.trace_func)
int_var.set(0)
rb1 = tk.Radiobutton(self, text = "Option 1", variable = int_var, value = 1)
rb1.grid(row=0, column=0, sticky=tk.W, padx=10, pady=10)
rb2 = tk.Radiobutton(self, text = "Option 2", variable = int_var, value = 2)
rb2.grid(row=1, column=0, sticky=tk.W, padx=10, pady=10)
button = tk.Button(self, text = 'Ok', command=new_top_level.destroy)
button.grid(row=2, column=0, pady=10)
self.grid()
def trace_func(self, *args):
radio_val = self.int_var.get()
print radio_val
EntryFrame.classvar = radio_val
def main():
root = tk.Tk()
my_frame = EntryFrame(root)
root.mainloop()
main()
答案 1 :(得分:-1)
通过稍作修改,现在我的代码工作正常。为某人发布新代码与我之前的相同点。可以在以下代码中看到更改:
import Tkinter as tk
class Parent:
classvar = 0
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master)
self.master.title("Parent Window")
self.master.geometry("400x100")
self.frame.grid()
self._button = tk.Button(self.frame, text="Create", width=10, command=self.new_window)
self._button.grid(row=0, column=0, sticky=tk.E+tk.W)
def new_window(self):
self.child_window = tk.Toplevel(self.master)
self.app = Child(self.child_window)
class Child(Parent):
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master)
self.master.title("Child Window")
self.frame.grid()
self._var = IntVar()
self._var.set(0)
self._var.trace("w", self.trace_fun)
self._radioButton = tk.Radiobutton(self.frame, text = "Option 1", variable = self._var, value = 1)
self._radioButton.grid(row=0, column=0, sticky=W, padx=10, pady=10)
self._radioButton2 = tk.Radiobutton(self.frame, text = "Option 2", variable = self._var, value = 2)
self._radioButton2.grid(row=1, column=0, sticky=W, padx=10, pady=10)
self._button = tk.Button(self.frame, text = 'Ok', command=self.master.destroy)
self._button.grid(row=2, column=0, pady=10)
def trace_fun(self, *args):
Parent.classvar = self._var.get()
print Parent.classvar
root = tk.Tk()
obj = Parent(root)
def main():
root.mainloop()
main()