alex deralu
alex deralu

Reputation: 589

How to display Option menu inside a frame in Tkinter?

I am trying to display a bunch of OptionMenu in tkinter. The problem is that once there are too many OptionMenu they go out of screen and they cannot be accessed anymore.

enter image description here

So I thought of implementing a full-screen scrollbar to solve this.

I followed this tutorial - link, in this, the full-screen scrollbar is implemented by putting buttons inside a frame

The code from the tutorial - Working code with buttons

So I tried to use this code but instead of buttons, use OptionMenu.

This is my code

from tkinter import *
import tkinter as tk

from tkinter import ttk



class App(tk.Frame):

    def __init__(self, master):
        tk.Frame.__init__(self, master)
        master.title('ATOM')
        master.geometry('650x650')

        
        main_frame = Frame(root)
        main_frame.pack(fill=BOTH, expand=1)

        # Create A Canvas
        my_canvas = Canvas(main_frame)
        my_canvas.pack(side=LEFT, fill=BOTH, expand=1)

        # Add A Scrollbar To The Canvas
        my_scrollbar = ttk.Scrollbar(main_frame, orient=VERTICAL, command=my_canvas.yview)
        my_scrollbar.pack(side=RIGHT, fill=Y)

        # Configure The Canvas
        my_canvas.configure(yscrollcommand=my_scrollbar.set)
        my_canvas.bind('<Configure>', lambda e: my_canvas.configure(scrollregion = my_canvas.bbox("all")))

        # Create ANOTHER Frame INSIDE the Canvas
        second_frame = Frame(my_canvas)

        # Add that New frame To a Window In The Canvas
        my_canvas.create_window((0,0), window=second_frame, anchor="nw")

        length=[1,2,3,4,5,6,7,8,9,10]
        variable_rsi_length = tk.StringVar(second_frame)
        rsi_len = ttk.OptionMenu(second_frame, variable_rsi_length,*length )
        variable_rsi_length.set('14')

        for thing in range(100):
            ttk.Button(second_frame, text=f'Button {thing} Yo!').grid(row=thing, column=0, pady=10, padx=10)


        my_label = Label(second_frame, text="It's Friday Yo!").grid(row=3, column=2)


        rsi_len.pack()
        self.pack()


if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    app.mainloop()

But this doesn't give any error on running in fact it does not even show the new window.

How can I implement this?

Upvotes: 1

Views: 379

Answers (1)

Kartikeya
Kartikeya

Reputation: 838

What's wrong is that you cannot use pack when its children are being managed by grid. To be more specific, the error is: _tkinter.TclError: cannot use geometry manager pack inside .!frame.!canvas.!frame which already has slaves managed by grid

So, what you can easily do is just use one type of geometry manager. Either use only "pack", or only "grid".

Here's a quick solution:

.
.
.

        for thing in range(100):
            ttk.Button(second_frame, text=f'Button {thing} Yo!').pack()


        my_label = Label(second_frame, text="It's Friday Yo!").pack()

        rsi_len.pack()
        self.pack()
.
.
.

Upvotes: 1

Related Questions