0

I am having a problem Disabling Menu's in my Tkinter App. Only I want to show them only on certain pages, I have tried to disable them in the init function of my app, but that didn't work, I have tried to disable them in the show frames function of my app but that didn't work and I have tried to disable them through the start page class of my app, in that I have tried to use self.menubar , parent.menubar and controler.menubar; But nothing seems to work. I would just code them on each individual page but this is the only way I found to even show them on any page. Any help would be much appreciated.

class App(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)
        container.grid_rowconfigure(0,weight = 1)
        container.grid_columnconfigure(0,weight = 1)

        menubar = tk.Menu(container)
        file = tk.Menu(menubar, tearoff = 0)
        file.add_command(label='Exit', command = quit)
        menubar.add_cascade(label='File',menu=file)
        tk.Tk.config(self, menu=menubar)

        self.frames = {}

        for F in (StartPage):
            frame = F(container,self)
            self.frames[F] = frame
            frame.grid(row=0,column=0,sticky='nsew')
            page = F
        self.show_frame(StartPage)

    def show_frame(self,cont):
        frame = self.frames[cont]
        frame.tkraise()

class StartPage(tk.Frame):

    def __init__(self,parent,controller):
        tk.Frame.__init__(self,parent)
        menubar.add_cascade(label='File',state=DISABLED)
        label = ttk.Label(self, text='Start', font = LARGE_FONT).pack()

main = App()
main.mainloop()
David Long
  • 39
  • 6

2 Answers2

0

This isn't a tkinter problem, it's how python works - to modify an object you need a reference to the object. This is true for tkinter widgets just as it is true for dictionaries, strings, or any other object in python.

In this case the object is part of the main application. You first need to save a reference to it:

class App(tk.Tk):

    def __init__(self,*args,**kwargs):
        ...
        self.menubar = tk.Menu(container)
        ...

In later code, you can now access this menu from the controller variable, which is a reference to the instance of App:

class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        controller.menubar.entryconfigure('File',state="disabled")

However, that likely won't do what you want since that code runs when the program starts up. I'm guessing you want the code to run when the page is selected. To do that, follow the instructions in this answer to the question How would I make a method which is run every time a frame is shown in tkinter

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I can't get the second part to work where you referenced the other question, here is what I have ```class StartPage(tk.Frame): def __init__(self,parent,controller): tk.Frame.__init__(self,parent) self.bind("<>", self.on_show_frame(controller)) – David Long Oct 21 '19 at 15:09
0

1st lets clean up this to reflect the PEP8 standard more closely for readability reason.

Added in the imports as those should have been in your example.

We need to replace the parenthesis in (StartPage) with brackets like this [StartPage]. This is because a single value in parenthesis is treated like a single value without parenthesis so you are trying to iterate over an object and not a list.

You should be more specific on what you are configuring. Instead of calling tk.tk.config() do self.config(menu=self.menubar).

for your StartPage class you are not going to be able to do anything to the menubar for several reason. First you do not define the menubar as a class attribute in your main tk class. 2nd you are not properly calling your master and container so I have changed the argument names in the init to better reflect what we are working with so you can see what you need to call.

Lastly the crux if the issue for disabling the menu you need to use entryconfig()

See below cleaned up code:

import tkinter as tk
import tkinter.ttk as ttk


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        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.menubar = tk.Menu(container)
        self.config(menu=self.menubar)
        file = tk.Menu(self.menubar, tearoff=0)
        file.add_command(label='Exit', command=quit)
        self.menubar.add_cascade(label='File', menu=file)

        self.frames = {}
        for F in [StartPage]:
            frame = F(self, container)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky='nsew')
            page = F
        self.show_frame(StartPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()


class StartPage(tk.Frame):
    def __init__(self, master, container):
        tk.Frame.__init__(self, container)
        master.menubar.entryconfig('File', state='disabled')
        ttk.Label(self, text='Start').pack()


main = App()
main.mainloop()
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79