I want to make a python tkinter app with multiple windows.
I want to be be able to click a button widget (message_button
) in one of the windows (PageOne
), and have it print a message using a label widget in the other window (PageTwo
).
I've attempted it with my message_fun()
(see below), but I can only manage to place the label in the same window (PageOne
).
I've also tried changing self
to PageTwo
in message_fun()
, but that only gives me an error message AttributeError: type object 'PageTwo' has no attribute 'tk'.
Thanks for any help!
import tkinter as tk
from tkinter import ttk
class MyPages(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
self.frames = {}
for F in (PageOne, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(PageOne)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
title_label = tk.Label(self, text="This is page one", font=("Verdana", 12))
title_label.pack(pady=10,padx=10)
navigate_button = ttk.Button(self, text="Page Two", command=lambda: controller.show_frame(PageTwo))
navigate_button.pack(side = tk.LEFT)
message_button = ttk.Button(self, text="Message button", command= self.message_fun)
message_button.pack(side = tk.LEFT)
def message_fun(self):
message_label = tk.Label(self, text='I want this message in page two', font=("Verdana", 12))
message_label.pack(side = tk.LEFT)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
title_label = tk.Label(self, text="This is page two", font=("Verdana", 12))
title_label.pack(pady=10,padx=10)
navigate_button = ttk.Button(self, text="Page one", command=lambda: controller.show_frame(PageOne))
navigate_button.pack(side = tk.LEFT)
app = MyPages()
app.mainloop()
CodePudding user response:
Every Page
gets as second argument controller
which gives access to MyPages
and MyPages
has frames
which gives access to all pages.
So you should first in __init__
keep controller
as self.controller
, and next you can use self.controller.frames[PageTwo]
to access second page in first page.
tk.Label(self.controller.frames[PageTwo], ...
import tkinter as tk
from tkinter import ttk
class MyPages(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
self.frames = {}
for F in (PageOne, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(PageOne)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
title_label = tk.Label(self, text="This is page one", font=("Verdana", 12))
title_label.pack(pady=10,padx=10)
navigate_button = ttk.Button(self, text="Page Two", command=lambda: controller.show_frame(PageTwo))
navigate_button.pack(side = tk.LEFT)
message_button = ttk.Button(self, text="Message button", command= self.message_fun)
message_button.pack(side = tk.LEFT)
def message_fun(self):
message_label = tk.Label(self.controller.frames[PageTwo], text='I want this message in page two', font=("Verdana", 12))
message_label.pack(side = tk.LEFT)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
title_label = tk.Label(self, text="This is page two", font=("Verdana", 12))
title_label.pack(pady=10,padx=10)
navigate_button = ttk.Button(self, text="Page one", command=lambda: controller.show_frame(PageOne))
navigate_button.pack(side = tk.LEFT)
app = MyPages()
app.mainloop()
``