Using tkinter, I'm trying to open one window from another window and doing so by creating the windows in a class.
This question talks about tkinter and class, but not multiple windows: Python Tkinter with classes
This question addresses multiple windows but it's creating an instance of the class: Python tkinter multiple windows. I don't want to create an instance of the class because tkdoc.com has the root = Tk() being passed into the class rather than creating an instance.
So, I have this example from https://www.pythontutorial.net/tkinter/tkinter-toplevel/ which does what I want but it creates a subclass of tk.TK rather than passing in root. I'm trying to adapt this example to pass in root because that's what the official docs do.
Here's the example of one window opening up another window that works, but it creates a subclass of tk.Tk:
import tkinter as tk
from tkinter import ttk
class Window(tk.Toplevel):
def __init__(self, parent):
super().__init__(parent)
self.geometry('300x100')
self.title('Toplevel Window')
ttk.Button(self,
text='Close',
command=self.destroy).pack(expand=True)
class App(tk.Tk):
def __init__(self):
super().__init__()
self.geometry('300x200')
self.title('Main Window')
# place a button on the root window
ttk.Button(self,
text='Open a window',
command=self.open_window).pack(expand=True)
def open_window(self):
window = Window(self)
window.grab_set()
if __name__ == "__main__":
app = App()
app.mainloop()
Here's my adaptation:
from tkinter import *
from tkinter import ttk
class Window(Toplevel):
def __init__(self, parent):
super().__init__(parent)
self.geometry('300x100')
self.title('Toplevel Window')
ttk.Button(self,
text='Close',
command=self.destroy).pack(expand=True)
class App():
def __init__(self, root):
super().__init__()
root.geometry('300x200')
root.title('Main Window')
# place a button on the root window
ttk.Button(root,
text='Open a window',
command=self.open_window).pack(expand=True)
def open_window(self):
window = Window(self)
window.grab_set()
if __name__ == "__main__":
root = Tk()
App(root)
root.mainloop()
The first window opens fine (class App()). I'm getting an AttributeError that occurs when attempting to open the second window (class Window(Toplevel)). Yet, the AttributeError is on the first window.
Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "c:\Users\User\Documents\Python\Python_Tutorial_net\Multiple_Windows_pass-in-Class.py", line 30, in open_window
window = Window(self)
^^^^^^^^^^^^
File "c:\Users\User\Documents\Python\Python_Tutorial_net\Multiple_Windows_pass-in-Class.py", line 7, in __init__
super().__init__(parent)
File "C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py", line 2678, in __init__
BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)
File "C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py", line 2623, in __init__
self._setup(master, cnf)
File "C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py", line 2592, in _setup
self.tk = master.tk
^^^^^^^^^
AttributeError: 'App' object has no attribute 'tk'
Appis not a tkinter widget. Parent of tkinter widget should be a widget as well.rootintoApp(root), then I have not created a tkinter widget? But in the first example,App(tk,TK)is a subclass oftk.Tkso that is a widget? However, the first window created byApp(root)does appear.rootis created byroot = Tk(), notApp(root).Window(self)callingclass Window(Toplevel)which is a subclass ofToplevel? It closes fine with theself.destroycommand in that class.