2015-01-10 5 views
0

저는 파이썬과 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() 

답변

-1

당신은 덮어 쓴 경우 여기 new 변수 : 그 두 문을 실행 한 후

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

, new는 최상위 레벨 클래스의 인스턴스와 동일합니다.

다음으로,이 코드를 실행합니다

new._var.trace("w", new.trace_fun) 

특히 :

new.trace_fun 

그래서, 당신은 속성을 이름 trace_fun에 액세스하려고 최상위 레벨 인스턴스가 있습니다. 오류 메시지는 Toplevel 클래스에 trace_fun이라는 속성이 없음을 알려줍니다.

편집 :

당신은 최상위 레벨 인스턴스 trace_fun 호출 할 수 없습니다 - 지금까지. 또한 Parent 인스턴스에서 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() 
+0

답장을 보내 주셔서 감사합니다. Toplevel 인스턴스 변수 이름을 new에서 new2로 변경하고 new2에서 trace_fun을 호출하려고했지만 여전히 동일한 오류가 발생합니다. 즉, Toplevel 인스턴스에는 trace_fun 속성이 없습니다. 네가 네가 나에게 제안한 것을 정확히 이해했으면 좋겠어. –

+0

@ J.I.W., 편집 내 대답보기. – 7stud

+0

@ 7stud., 자세한 설명을 읽어 주셔서 감사합니다. 두 프레임의 상호 작용과 관련된 몇 가지 개념을 이해하는 데 도움이되었습니다. –

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

중요한 차이점을 설명하면 답이 더 나을 것입니다. 너는 무엇을 바꾸 었는가? 설명없이 독자는 차이점을 찾기 위해 코드를 라인별로 비교해야합니다. –