2016-07-11 12 views
1

Ich versuche einen objektorientierten Ansatz zu verwenden, um eine Klasse zu erstellen, die von tkinter's Toplevel erbt, ausgelöst durch Drücken einer Schaltfläche im Hauptfenster.Python tkinter - erfolgreich erben von Toplevel

Der aktuelle Code löst einen AttributeError aus ('MakeWindow' -Objekt hat kein Attribut 'tk'). Kann mir jemand in die richtige Richtung zeigen?

#! python3 
import tkinter as tk 


class Application: 
    def __init__(self, master): 
     self.frame = tk.Frame(master) 
     self.frame.pack()  
     self.okButton = tk.Button(self.frame, text="OK", 
            command=self.window_maker).pack() 
     self.quitButton = tk.Button(self.frame, text="Close", 
            command=self.frame.quit).pack() 
    def window_maker(self): 
     MakeWindow("A message to Toplevel") 


class MakeWindow(tk.Toplevel): 
    def __init__(self, message): 
     super().__init__(self) 
     self.message = message 
     self.display = tk.Label(self, text=message) 
     self.display.pack() 


if __name__ == '__main__': 
    root = tk.Tk() 
    app = Application(root) 
    root.mainloop() 

Vollzurückverfolgungs:

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "C:\Users\r\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 1550, in __call__ 
    return self.func(*args) 
    File "C:/Users/r/PycharmProjects/tkinter_gui/y.py", line 15, in window_maker 
    MakeWindow("A message to Toplevel") 
    File "C:/Users/r/PycharmProjects/tkinter_gui/y.py", line 20, in __init__ 
    super().__init__(self) 
    File "C:\Users\r\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 2182, in __init__ 
    BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra) 
    File "C:\Users\r\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 2132, in __init__ 
    BaseWidget._setup(self, master, cnf) 
    File "C:\Users\r\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 2110, in _setup 
    self.tk = master.tk 
AttributeError: 'MakeWindow' object has no attribute 'tk' 
+0

Konnten Sie eine vollständige Rückverfolgung geben und die Einrückung korrigieren? – jonrsharpe

+1

Sie haben einen einfachen Tippfehler - 'super() .__ init __()' wird gut funktionieren. Im Moment stellen Sie die neue MakeWindow-Instanz als "Master" zur Verfügung, was nicht möglich ist. – jonrsharpe

+0

Das funktioniert, danke! – qmsack

Antwort

1

Das Problem ist die super().__init__(self) es super().__init__() sein sollte. Außerdem ist es in diesem Fall nicht erforderlich, super zu verwenden (siehe What does 'super' do in Python?). Der folgende Code funktioniert:

import tkinter as tk 


class Application: 
    def __init__(self, master): 
     self.frame = tk.Frame(master) 
     self.frame.pack()  
     self.okButton = tk.Button(self.frame, text="OK", 
            command=self.window_maker).pack() 
     self.quitButton = tk.Button(self.frame, text="Close", 
            command=self.frame.quit).pack() 
    def window_maker(self): 
     MakeWindow("A message to Toplevel") 


class MakeWindow(tk.Toplevel): 
    def __init__(self, message): 
     tk.Toplevel.__init__(self) #instead of super 
     self.message = message 
     self.display = tk.Label(self, text=message) 
     self.display.pack() 


if __name__ == '__main__': 
    root = tk.Tk() 
    app = Application(root) 
    root.mainloop() 
+0

Warum benutzt du nicht 'super'? Das brauchst du nicht, aber es ist viel besser. – jonrsharpe

+0

Danke - also wenn ich super() benutze, wird kein 'self' benötigt, tk.Topelevel .__ init __ (selbst) benötigt 'self'. Pycharm beklagt sich über Letzteres ("Erwarteter Typ 'Toplevel', aber stattdessen 'Make Window'), aber es funktioniert gut. Danke und Danke für den Link! – qmsack