Cannot Update tkinter Frame or Label using Instance method

Question:

I’m having an update problem in tkinter GUI, for past two days, I have searched a lot, Cant find something specific to my problem.This post Tkinter updating labels in stacked frame windows come close to my problem but not exactly. I am using classes to structure my application… The structure is given here Application structure image ( SOF not letting me embed images but link is provided )

From above structure you can see, I’m trying to make changes in DetailFrame from ListProduct Frame, now the code is reaching there and changing the values successfully but not updating the label, I’m using config method to change label… and frame background,but no luck..

I have tried StringVar as well for updating label, but nothing… Sample Code is provided below…

This application is a part of main app and for Original Code Structure Thanks to .. Bryan Oakley

class ProductWindow(tk.Tk):

    def __init__(self):

        tk.Tk.__init__(self)
        self.geometry("600x500")
        
        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.notebook = ttk.Notebook(container)
        self.notebook.grid(row=0, column=0, sticky='nsew')


        self.new_product_tab = tk.Frame(self.notebook, bg='#233223' )
        self.list_product_tab = tk.Frame(self.notebook, bg='#323232')
        self.edit_product_tab = tk.Frame(self.notebook, bg='#433434')

        # Adding Tabs to Notebook
        self.notebook.add(self.new_product_tab, text="  Add New Product     ")
        self.notebook.add(self.list_product_tab, text="  List All Product     ")
        self.notebook.add(self.edit_product_tab, text="  Edit Product       ")

        
        self.productframe = EditProductFrame(self.edit_product_tab)
        self.detailframe = DetailFrame(self.productframe)


        button = tk.Button(self.list_product_tab, text="Change background in Edit Form", command=self.change_method)
        button.pack()



    def change_method(self):

        print("Trying to change the frame")

        self.productframe.raise_edit_frame(DetailFrame)
        self.detailframe.change_bg('green')

        self.notebook.select(self.edit_product_tab)






if __name__ == "__main__":

    testObj = ProductWindow()
    testObj.mainloop()


In another file, I have DetailFrame below.

class EditProductFrame(tk.Frame):

    def __init__(self, parent):
        

        print("Edit product frame constructor is called...")

        tk.Frame.__init__(self, parent)
        self.pack(side='top', fill='both', expand=True)
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        # define frames and pack them in
        self.frames = {}

        for F in {DetailFrame, EditFrame}:

            frame = F(self)
            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky='nsew')

        self.raise_edit_frame(DetailFrame)


    def raise_edit_frame(self, container):

        frame = self.frames[container]
        frame.tkraise()




class EditFrame(tk.Frame):

    def __init__(self, parent):

        tk.Frame.__init__(self, parent)
        self.config(bg='green')


        label = tk.Label(self, text="Edit Page",)
        label.pack(pady=0,padx=0)

        tk.Button(self, text="Go to Detail", command=lambda:parent.raise_edit_frame(DetailFrame)).pack()




class DetailFrame(tk.Frame):

    def __init__(self, parent):

        print("something detail view")

        tk.Frame.__init__(self, parent)
        self.config(bg='blue')



        self.label = tk.Label(self, text='Original Label')
        self.label.pack(pady=0,padx=0)

        tk.Button(self, text="Go to Edit Frame", command=lambda:parent.raise_edit_frame(EditFrame)).pack()





    def change_bg(self, color):

        # doesn't update the background
        self.config(bg=color)

        # doesn't update the Label text
        self.label.config(text='Changed Label')


        # print the correct changed value = 'Changed Label'
        print(self.label.cget('text'))

Thanks …

Asked By: alirehman

||

Answers:

Note that you have created another instance of DetailFrame (self.detailframe) inside ProductWindow but it is not visible since no layout function is called on it. Actually there is already an instance of DetailFrame created when creating instance of EditProductFrame, so you need to call change_bg() on this instance instead:

class ProductWindow(tk.Tk):

    def __init__(self):

        tk.Tk.__init__(self)
        self.geometry("600x500")

        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.notebook = ttk.Notebook(container)
        self.notebook.grid(row=0, column=0, sticky='nsew')


        self.new_product_tab = tk.Frame(self.notebook, bg='#233223' )
        self.list_product_tab = tk.Frame(self.notebook, bg='#323232')
        self.edit_product_tab = tk.Frame(self.notebook, bg='#433434')

        # Adding Tabs to Notebook
        self.notebook.add(self.new_product_tab, text="  Add New Product     ")
        self.notebook.add(self.list_product_tab, text="  List All Product     ")
        self.notebook.add(self.edit_product_tab, text="  Edit Product       ")

        # -- there is an instance of DetailFrame created inside EditProductFrame
        self.productframe = EditProductFrame(self.edit_product_tab)
        # -- so don't create another instance of DetailFrame
        #self.detailframe = DetailFrame(self.productframe)

        button = tk.Button(self.list_product_tab, text="Change background in Edit Form", command=self.change_method)
        button.pack()

    def change_method(self):

        print("Trying to change the frame")

        self.productframe.raise_edit_frame(DetailFrame)
        #self.detailframe.change_bg('green')
        # -- call change_bg() on the instance of DetailFrame inside EditProductFrame
        self.productframe.frames[DetailFrame].change_bg('green')

        self.notebook.select(self.edit_product_tab)

Another option is to make self.detailframe the reference to the instance of EditFrame inside EditProductFrame:

self.detailframe = self.productframe.frames[DetailFrame]
Answered By: acw1668
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.