Home > Blockchain >  Clicking a button in one of the window creates a label in the other window
Clicking a button in one of the window creates a label in the other window

Time:11-19

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()
``
  • Related