tkintertkinter-menu

Create a menu inside a Class


I have been resisting posting this question but have finally decided to put my pride in my pocket and admit that I cannot get the menu creation section of my program to work. I still do not seem to have been able to fully grasp the workings of Classes. The program that I have written is basically a Cashbook keeping track of cash receipts and expenses and analysing them to various accounts. This all works fine. Then I also added a second window to add analysis items. This also works fine. However, finally I have tried to add a menu but cannot get it to work. When I run the program it does not throw out any errors but no menu ('File/Exit') appears. Can someone please look at the following (Menu_ex) code and tell me where it fails? Thank you in anticipation.

import tkinter as tk
from tkinter import ttk
from tkinter import Tk, Frame, Menu
from tkcalendar import Calendar, DateEntry
import sqlite3
import datetime as dt
import time
from tkinter import messagebox as msgbox
from prettytable import PrettyTable
from prettytable import MSWORD_FRIENDLY
import subprocess, sys

class Window(tk.Toplevel):
    def __init__(self, parent):
        super().__init__(parent)

        self.geometry('450x200')
        self.title('Add a new Analysis Item')


        def Item_sel(): 
            """ Set the value of the selected Radio buttons"""

            global item_choice
            global Item_Cat

            item_choice=Item_radio_var.get()

            
            if item_choice==1:


                Item_Analyse.config(state='normal')
                print('Item_radio_var = ' + str(item_choice))
                Item_Cat='IncCat'
                print('The item selected is ' + Item_Cat)
                Item_Analyse.focus()
                
            elif item_choice==2:
                #Item_Analyse.delete(0,tk.END)
                Item_Analyse.config(state='normal')
                print('Item_radio_var = ' + str(item_choice))
                Item_Cat='ExpCat'
                print('The item selected is ' + Item_Cat)
                Item_Analyse.focus()

class Menu_ex():

    def __init__(self,parent):    
        super().__init__(parent)

        #self.initUI()

    def initUI(self):

        menubar=Menu(self.parent)
        self.parent.config(menu=menubar)

        fileMenu=Menu(menubar)
        fileMenu.add_command(label='Exit', command=self.onExit)
        menubar.add_cascade(label='File',menu=fileMenu)

    def onExit(self):

        self.quit()

class MainWindow(tk.Tk):

    def __init__(self):    
        super().__init__()
        
        

        global format_date
        date = dt.datetime.now()
        format_date=f"{date:%Y-%m-%d}"
        print(format_date)
        self.title('My Nedbank Credit Card')
        self.geometry('1130x450')
        self.grid_rowconfigure(0,weight=1)
        self.grid_columnconfigure(0,weight=1)
        self.resizable(width=False,height=False)
     

        """Create a Frame inside a Window to contain widgets"""

        frame1 = ttk.Frame(self)
        frame1.grid(column=0,row=0, pady=5, sticky='news')

        """Create widgets in Frame1"""

        l_Sub = tk.Label(frame1,text='Nedbank Credit Card', fg='blue')
        l_Sub.config(font=('Courier Bold', 16))
        l_Sub.place(relx=.05,rely=.5)
        l_Sub.grid(row=0, column=0, pady=10,sticky='news',columnspan=4)

        l_SubHead = tk.Label(frame1,text='Enter transaction data', fg='blue')
        l_SubHead.config(font=('Courier Bold', 12))
        l_SubHead.place(relx=.05,rely=.5)
        l_SubHead.grid(row=1, column=0, pady=10,sticky='news',columnspan=4)

def open_window(self):
        window = Window(self)
        window.grab_set()

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

Solution

  • Short answer is that you weren't actually creating an instance of your Menu class so it would never be displayed

    Below code displays the menu and fixes the exit button

    import tkinter as tk
    from tkinter import ttk
    from tkinter import Tk, Frame, Menu
    #from tkcalendar import Calendar, DateEntry
    import sqlite3
    import datetime as dt
    import time
    from tkinter import messagebox as msgbox
    #from prettytable import PrettyTable
    #from prettytable import MSWORD_FRIENDLY
    import subprocess, sys
    
    class Window(tk.Toplevel):
        def __init__(self, parent):
            super().__init__(parent)
    
            self.geometry('450x200')
            self.title('Add a new Analysis Item')
    
    
            def Item_sel(): 
                """ Set the value of the selected Radio buttons"""
    
                global item_choice
                global Item_Cat
    
                item_choice=Item_radio_var.get()
    
                
                if item_choice==1:
    
    
                    Item_Analyse.config(state='normal')
                    print('Item_radio_var = ' + str(item_choice))
                    Item_Cat='IncCat'
                    print('The item selected is ' + Item_Cat)
                    Item_Analyse.focus()
                    
                elif item_choice==2:
                    #Item_Analyse.delete(0,tk.END)
                    Item_Analyse.config(state='normal')
                    print('Item_radio_var = ' + str(item_choice))
                    Item_Cat='ExpCat'
                    print('The item selected is ' + Item_Cat)
                    Item_Analyse.focus()
    
    class Menu_ex():
    
        def __init__(self,parent):    
            self.parent = parent
            self.initUI()
    
        def initUI(self):
    
            self.menubar=Menu(self.parent)
            self.parent.config(menu=self.menubar)
    
            fileMenu=Menu(self.menubar)
            fileMenu.add_command(label='Exit', command=self.onExit)
            self.menubar.add_cascade(label='File',menu=fileMenu)
    
        def onExit(self):
    
            self.parent.destroy()
    
    class MainWindow(tk.Tk):
    
        def __init__(self):    
            super().__init__()
            
            
    
            global format_date
            date = dt.datetime.now()
            format_date=f"{date:%Y-%m-%d}"
            print(format_date)
            self.title('My Nedbank Credit Card')
            self.geometry('1130x450')
            self.grid_rowconfigure(0,weight=1)
            self.grid_columnconfigure(0,weight=1)
            self.resizable(width=False,height=False)
            self.menu = Menu_ex(self)
         
    
            """Create a Frame inside a Window to contain widgets"""
    
            frame1 = ttk.Frame(self)
            frame1.grid(column=0,row=0, pady=5, sticky='news')
    
            """Create widgets in Frame1"""
    
            l_Sub = tk.Label(frame1,text='Nedbank Credit Card', fg='blue')
            l_Sub.config(font=('Courier Bold', 16))
            l_Sub.place(relx=.05,rely=.5)
            l_Sub.grid(row=0, column=0, pady=10,sticky='news',columnspan=4)
    
            l_SubHead = tk.Label(frame1,text='Enter transaction data', fg='blue')
            l_SubHead.config(font=('Courier Bold', 12))
            l_SubHead.place(relx=.05,rely=.5)
            l_SubHead.grid(row=1, column=0, pady=10,sticky='news',columnspan=4)
    
    def open_window(self):
            window = Window(self)
            window.grab_set()
    
    if __name__ == "__main__":
        app = MainWindow()
        app.mainloop()