2017-02-16 4 views
0

Ich versuche einen Instant Messenger mit mehreren Frames zu erstellen und habe Code aus einem Tutorial eingefügt, dem ich gefolgt bin. Mein Eintrag "e" soll die Benutzereingabe in einer Textdatei speichern und in einem Textfeld anzeigen, aber wenn ich e.get() aufruft, erhalte ich den folgenden Fehler. Es behandelt e als ein Attribut anstelle eines Objekts (ich denke) und ich weiß nicht warum.Tkinter: Objekt kann nicht aufgerufen werden, da das Attribut fehlt

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "C:\Users\Douglas Rouse\AppData\Local\Programs\Python\Python35-32\lib\idlelib\run.py", line 119, in main 
    seq, request = rpc.request_queue.get(block=True, timeout=0.05) 
    File "C:\Users\Douglas Rouse\AppData\Local\Programs\Python\Python35-32\lib\queue.py", line 172, in get 
    raise Empty 
queue.Empty 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "C:\Users\Douglas Rouse\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1550, in __call__ 
    return self.func(*args) 
    File "C:\Users\Douglas Rouse\Google Drive\Python\New structure.py", line 78, in callback 
    f.write("Douglas:"+self.e.get()+"\n") 
AttributeError: 'PageOne' object has no attribute 'e' 

Ich kann nicht sagen, warum er denkt, e ein Attribut ist oder warum es nicht e (der Eintrag) als ein Objekt aufrufen und nicht die Klasse selbst. Hier ist der Code, an dem ich gerade arbeite. Der Fehler liegt in der Rückruffunktion.

import tkinter as tk 
LARGE_FONT=("Verdana", 12) 


class SeaofBTCapp(tk.Tk): 

    def __init__(self, *args, **kwargs): 
     tk.Tk.__init__(self, *args, **kwargs) 
     container = tk.Frame(self) 

     container.grid() 

     container.grid_rowconfigure(0, weight=1) 
     container.grid_columnconfigure(0, weight=1) 

     self.frames = {} 

     frame = StartPage(container, self) 
     frame_ = PageOne(container, self) 

     self.frames[StartPage] = frame 
     self.frames[PageOne] = frame_ 

     frame.grid(row=0, column=0, sticky="nsew") 
     frame_.grid(row=0, column=0, sticky="nsew") 

     self.show_frame(StartPage) 

    def show_frame(self, cont): 
     frame = self.frames[cont] 
     frame.tkraise() 

class StartPage(tk.Frame): 

    def __init__(self, parent, controller,*args): 
     tk.Frame.__init__(self, parent) 
     usrlabel = tk.Label(self, text="Input Username", font=LARGE_FONT) 
     usrlabel.grid(pady=10,padx=10) 
     usrentry = tk.Entry(self) 
     #usrentry.grid() 
     global uu 
     uu = usrentry.get() 

     #command within button cant throw args to funcs. Use lambda to throw those args to the func instead 
     button1 = tk.Button(self, text="Visit Page 1",command= 
          lambda: controller.show_frame(PageOne)) 
     button1.grid() 

class PageOne(tk.Frame): 

    def __init__(self, parent, controller): 

     tk.Frame.__init__(self, parent) 
     label = tk.Label(self, text="Page 1", font=LARGE_FONT) 
     label.grid() 

     #command within button cant throw args to funcs. Use lambda to throw those args to the func instead 
     button1 = tk.Button(self, text="Start Page",command=lambda:controller.show_frame(StartPage)) 
     button1.grid() 

     file = open("htfl.txt","r") #opens file 
     #print(file.read(1)) 
     a = file.read() 
     b = file.read() 
     print(file.read()) 

     #entry 
     e = tk.Entry(self,width= 40) 
     e.grid(row=10,column=0,sticky = "W") 
     #text 
     T = tk.Text(self, height=9, width=30) 
     T.grid(row=3,column= 0) 
     #T.insert(END,a) 
     b = tk.Button(self, text="Send", width=10, command=self.callback).grid(row=10,column=2) 

    def callback(self,*args): 
     f = open("htfl.txt","a") 
     f.write("Douglas:"+self.e.get()+"\n") 
     e.delete(0, 'end') 
     #print (e.get()) 
     #Button 



app = SeaofBTCapp() 

Antwort

1

Die e Sie in PageOne ‚s __init__ Methode sind die Schaffung ist eine lokale Variable und nicht von außen verwiesen werden kann. Was Sie tun möchten, ist e ein Attribut Ihres Objekts zu machen. Dies führt in

self.e = tk.Entry(self,width= 40) 

Wenn Sie nun dieses Attribut in Ihrem Objekt zugreifen möchten, verwenden Sie self.e statt e.

+2

Ich denke, diese Antwort wäre besser, wenn das Beispiel die Verwendung von "self.e" zeigt, anstatt die Änderung im folgenden Satz zu begraben. –

+0

@TidB Ich bin mir nicht ganz sicher, ob ich das verstehe. Ich habe versucht, es mit Self e.write ("Douglas:" + self.e.get() + "\ n") –

+0

@douglasrouse Warum versuchen Sie jetzt 'self.e.write (...)' stattdessen als zuvor 'f.write (...)'? Die Version mit 'f' war in Ordnung. – TidB

Verwandte Themen