0

I'm totally new in python and tkinter, therefore I would like to ask someone for help. I preparing a GUI application with multiframe tkinter application. My problem is that I want to change btn1 properties, e.g. background in frame1 by presseing btn2 in frame2 and it is not workig and I'm totally frustruated where is the problem Here is my code

#-----------------------------------------------------------

from tkinter import *
import tkinter as tk            

state=0

class SmartApp(tk.Tk):
    def __init__(self, *args,**kwargs):
       tk.Tk.__init__(self,*args,**kwargs)
       tk.Tk.wm_geometry(self,"800x480")
 
       container=tk.Frame(self)
       container.pack(side="top", fill="both", expand= True)
       container.grid_rowconfigure(0,weight=1)
       container.grid_columnconfigure(0,weight=1)
       self.frames= {}  #dictionary for frames, contain the list of frames
       for frames in (Frame1,Frame2):
          page_name=frames.__name__
          frame=frames(parent=container,controller=self)
          self.frames[page_name]=frame
          frame.grid(row=0,column=0 , sticky="nsew") #
    self.show_frame("Frame1")

def show_frame(self,cont):
    frame=self.frames[cont]
    frame.tkraise() # raise to the front


class Frame1(tk.Frame):
def __init__(self,parent,controller):
    tk.Frame.__init__(self,parent)
    self.controller=controller
    global state

    label=tk.Label(self,text="Frame1")
    label.place(x=50,y=50)

    btn_1=tk.Button(self,text="go to Frame2", command=lambda:controller.show_frame("Frame2"))
    btn_1.place(x=500,y=200)


    if state==1:
        btn_1.configure(bg='green') # this I wolud reach

class Frame2(tk.Frame):
def __init__(self,parent,controller):
    tk.Frame.__init__(self,parent)
    self.controller=controller

    right_frame=tk.Frame(self,bg='#FF0000')
    right_frame.pack(side=RIGHT,expand=YES, fill=BOTH)

    left_frame = tk.Frame(self, bg='#00FF00')
    left_frame.pack(side=LEFT, expand=YES, fill=BOTH)

    main_menu_btn = tk.Button(right_frame, text="back to Frame1", command=self.hide)
    main_menu_btn.place(x=240, y=300)
    

    btn_2=tk.Button(right_frame, text="Change",command=lambda:self.activate) # with this I would like to change btn_1 background
    btn_2.grid(row=0, rowspan=2, column=3)

def activate(self):
    global state
    state=1
    return (state)
    
def hide(self):
    self.controller.show_frame("Frame1")


if __name__ == "__main__":
app = SmartApp()
app.mainloop()
peter
  • 1
  • 1

1 Answers1

0

Try this:

import tkinter as tk


class SmartApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        super().wm_geometry("800x480")
 
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}  #dictionary for frames, contain the list of frames
        for Frame in (Frame1, Frame2):
            frame = Frame(container, controller=self)
            frame.grid(row=0, column=0, sticky="news")
            self.frames.update({Frame.__name__: frame})
        self.show_frame("Frame1")

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise() # raise to the front


class Frame1(tk.Frame):
    def __init__(self, master, controller):
        super().__init__(master)
        self.controller = controller

        self.label = tk.Label(self, text="Frame1")
        self.label.place(x=50, y=50)

        self.btn_1 = tk.Button(self, text="go to Frame2",
                          command=lambda: controller.show_frame("Frame2"))
        self.btn_1.place(x=500, y=200)


    def change_btn_bg(self):
        self.btn_1.configure(bg="green")


class Frame2(tk.Frame):
    def __init__(self, master, controller):
        super().__init__(master)
        self.controller = controller

        right_frame = tk.Frame(self, bg="#FF0000")
        right_frame.pack(side="right", expand=True, fill="both")

        left_frame = tk.Frame(self, bg="#00FF00")
        left_frame.pack(side="left", expand=True, fill="both")

        main_menu_btn = tk.Button(right_frame, text="back to Frame1",
                                  command=self.hide)
        main_menu_btn.place(x=240, y=300)

        btn_2 = tk.Button(right_frame, text="Change",
                          command=self.activate)
        btn_2.grid(row=0, rowspan=2, column=3)

    def activate(self):
        # Call Frame1's `change_btn_bg` method
        self.controller.frames["Frame1"].change_btn_bg()
        
    def hide(self):
        self.controller.show_frame("Frame1")


if __name__ == "__main__":
    app = SmartApp()
    app.mainloop()

First of all, I cleaned up your code. Second of all, you only checked the value of state once. You don't have to use a flag if you directly call the correct method.

TheLizzard
  • 7,248
  • 2
  • 11
  • 31
  • Thank you ...it seems its solve my problem now – peter Feb 28 '21 at 19:40
  • @peter Happy to help but if this was the answer you were looking for, please consider accepting it so that other people don't waste time coming up with the same solution. – TheLizzard Feb 28 '21 at 19:55