跟踪在子类中定义的radiobutton值并将其传递给Python中的父类

2024-06-02 06:06:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Python和Tkinter还不熟悉,所以不知道哪种方法最简单。有人可以检查下面的代码,告诉我如何跟踪在子类中定义的radiobutton返回的值并将其传递给父类。编译后出现以下错误:

AttributeError: Toplevel instance has no attribute 'trace_fun'

我不知道为什么会出现这个错误,因为我已经在子类body中定义了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()

Tags: textselfnewinitvardeftracecolumn
2条回答

通过稍作修改,现在我的代码可以完美地工作了。发布新代码的人陷入同一点,我早些时候。可以在下面的代码中看到更改:

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()

您在此处重写了new变量:

   new = Frame.__init__(self)
   new = Toplevel(self)

在这两个语句执行之后,new等于顶级类的一个实例。在

接下来,此代码将执行:

^{pr2}$

尤其是:

new.trace_fun

因此,您有一个顶级实例尝试访问名为trace_fun的属性。错误消息告诉您顶级类没有任何名为trace_fun的属性。在

编辑:

你永远不能在顶级实例上调用trace_fun。也不能在父实例上调用trace_fun。所以打印一份你的程序,然后拿一支笔圈出所有顶层实例的变量,然后圈出所有作为父实例的变量。你不能对这些变量调用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()

相关问题 更多 >