2017-02-26 6 views
1

Ich versuche ein Instant-Messenger-Programm zu erstellen, das über ein Netzlaufwerk funktioniert und einen Code von @Bryan Oakley verwendet, um zwischen tkinter-Frames zu wechseln. Der erste Frame soll ein Eintrag für einen Benutzernamen sein, der in einer txt-Datei gespeichert wird. Ich möchte diesen Frame überspringen, wenn mein Programm feststellt, dass der Benutzername bereits einmal gespeichert wurde. Ich bekomme jedoch den folgenden Fehler, wenn ich dies versuche.Es kann kein weiterer Tkinter-Frame angezeigt werden, wenn eine bestimmte Bedingung erfüllt ist.

Traceback (most recent call last): 
    File "C:\Users\Douglas Rouse\Google Drive\Python\New structure.py", line 260, in <module> 
    app = ChatApp() 
    File "C:\Users\Douglas Rouse\Google Drive\Python\New structure.py", line 73, in __init__ 
    frame = StartPage(self.container, self) 
    File "C:\Users\Douglas Rouse\Google Drive\Python\New structure.py", line 129, in __init__ 
    self.check_user() 
    File "C:\Users\Douglas Rouse\Google Drive\Python\New structure.py", line 144, in check_user 
    ChatApp.show_frame(ChatApp,[PageOne]) 
    File "C:\Users\Douglas Rouse\Google Drive\Python\New structure.py", line 106, in show_frame 
    self.frame = self.frames[cont] 
AttributeError: type object 'ChatApp' has no attribute 'frames' 

Ich bin ziemlich neu zu Python, so eine Erklärung, wo genau ich falsch gelaufen wäre, würde geschätzt werden!

class ChatApp(tk.Tk): 

    def __init__(self, *args, **kwargs): 
     tk.Tk.__init__(self, *args, **kwargs) 
     tk.Tk.wm_title(self,"Messenger") 

     self.container = tk.Frame(self) 
     self.container.grid() 
     self.container.grid_rowconfigure(0, weight=1) 
     self.container.grid_columnconfigure(0, weight=1) 


     self.frames = {} 
     frame = StartPage(self.container, self) 
     self.frame_ = PageOne(self.container, self) 
     frame1 = BanPage(self.container, self) 

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

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

     self.show_frame(StartPage) 
     #ban() 




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


class StartPage(tk.Frame): 

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

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

    def save_user(self,*args): 
     usr = open("user.txt","a") 
     self.public_usr = open("publicusr.txt","a") 
     self.public_usr.write(self.usrentry.get()) 
     usr.write(self.usrentry.get()) 
     self.usrentry.delete(0, 'end') 

    def check_user(self): 
     usrcount=0 
     with open ("user.txt","rb") as usr: 
      for line in usr: 
       usrcount+=1 
      if usrcount == 1: 
       ChatApp.show_frame(ChatApp,[PageOne]) 
       print(usrcount) 

Antwort

1

Diese Codezeile wird das Problem verursacht:

ChatApp.show_frame(ChatApp,[PageOne]) 

Sie rufen show_frame nicht auf einer Instanz von ChatApp, aber auf das Klassenobjekt selbst. Die Klasse hat das Attribut nicht, weshalb Sie den Fehler "ChatApp" haben kein Attribut "frames"

Sie können show_frame für die Klasse nicht aufrufen, Sie müssen es für eine Instanz der Klasse aufrufen. In Ihrem Fall wird die Instanz als controller übergeben, die Sie speichern müssen, damit Sie sie später verwenden können.

class StartPage(tk.Frame): 

    def __init__(self, parent, controller,*args): 
     self.controller = controller 
     ... 

    def check_user(self): 
     ... 
      if usrcount == 1: 
       self.controller.show_frame(PageOne) 
       ... 

Ich denke, Sie werden auch das Problem, dass show_frame aufgerufen wird, bevor er etwas anderes als ein leeres Wörterbuch ist. Das liegt daran, dass Sie check_user sofort anrufen, wenn StartPage erstellt wird, was passiert, bevor Sie irgendetwas in self.frames einfügen.

+0

Vielen Dank. Die Erklärung war sehr hilfreich. Sie hatten Recht mit dem leeren Wörterbuch, das ich zu lösen versuchte, aber ich stelle mir vor, dass die Etikette vorschreibt, dass ich das in einer anderen Frage stelle, nachdem ich versucht habe, es selbst herauszufinden. Vielen Dank für Ihre Hilfe. –

Verwandte Themen