Search code examples
pythonooptkinteroptionmenu

How align Optionmenu using grid in centre of window in tkinter?


I am trying to align Optionmenu in center and side by side but whenever I uncomment the .grid() statements nothing is displayed in window it becomes blank.

import tkinter as tk
from utils import editionMap, topicMap, langMap

class OptionMenu(tk.Frame):

    def __init__(self, master, status, *options):
        self.frame = tk.Frame(master)
        self.frame.pack()

        self.status = tk.StringVar()
        self.status.set(status)

        self.dropdown = tk.OptionMenu(self.frame, self.status, *options)
        self.dropdown.pack()


def main():
    root = tk.Tk()
    Edition_Filter = OptionMenu(root, "Edition", *editionMap.keys())
    #Edition_Filter.grid(row=0, column=0)  <---Uncomment
    Language_Filter = OptionMenu(root, "Language", *langMap.keys())
    #Language_Filter.grid(row=0, column=1) <---Uncomment
    Topic_Filter = OptionMenu(root, "Topic", *topicMap.keys())
    #Topic_Filter.grid(row=0, column=2)    <---Uncomment

    root.mainloop()

if __name__ == '__main__':
    main()

I want the display option menu as Edition Language Topic side by side horizontally.

My actual output is:

enter image description here


Solution

  • You mix two different technics

    First: inheriting

    class OptionMenu(tk.Frame): # <-- with Frame
    
        def __init__(self, master, status, *options):
    
            super().__init__(master) # <-- with super()
    

    Second: including

    class OptionMenu(): # <-- without Frame
    
        def __init__(self, master, status, *options):
    
            self.frame = tk.Frame(master) # <-- create inner widget
    

    First create real widget which can use menu.pack() or menu.grid()

    Second doesn't create widget - it create normal class with widget inside and you have to use menu.frame.pack() or menu.frame.grid()


    Example with real widget

    import tkinter as tk
    
    class OptionMenu(tk.Frame): # <-- with Frame
    
        def __init__(self, master, status, *options):
    
            super().__init__(master) # <-- with super()
    
            self.status = tk.StringVar()
            self.status.set(status)
    
            # use `self` as parent for widgets inside
    
            self.dropdown = tk.OptionMenu(self, self.status, *options)
            self.dropdown.pack()
    
    
    def main():
    
        editionMap = {1:"English", 2:"German", 3:"Russian"}
        langMap = {1:"English", 2:"German", 3:"Russian"}
        topicMap = {1:"English", 2:"German", 3:"Russian"}
    
        root = tk.Tk()
    
        Edition_Filter = OptionMenu(root, "Edition", *editionMap.keys())
        Edition_Filter.grid(row=0, column=0)
    
        Language_Filter = OptionMenu(root, "Language", *langMap.keys())
        Language_Filter.grid(row=0, column=1)
    
        Topic_Filter = OptionMenu(root, "Topic", *topicMap.keys())
        Topic_Filter.grid(row=0, column=2)
    
        root.mainloop()
    
    if __name__ == '__main__':
        main()