Search code examples
pythontkinter

Scrollbar grays out on tkinter


When I use

 my_canvas.configure(yscrollcommand=scrollbar.set)

my scrollbar goes gray.

relevant code:

 window.geometry("1550x500")
    main_frame = Frame(window, background="blue")
    main_frame.grid(sticky="news")
    my_canvas = Canvas(main_frame)
    my_canvas.grid(row=0, column=9, sticky='news')

    scrollbar = Scrollbar(main_frame, command=my_canvas.yview)
    scrollbar.grid(row=0, column=10, sticky="ns")

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

    def edit_password():
        text1.config(state="normal")
        text2.config(state="normal")
        text3.config(state="normal")
        text4.config(state="normal")

    vault_label = tk.Label(my_canvas, text="Welcome to your password vault", font=("Time New Roman", 20))
    vault_label.grid(column=1, row=0)

    add_button = tk.Button(my_canvas, text="Add new info", command=add_entry)
    add_button.grid(column=0, padx=8)

    website_label = tk.Label(my_canvas, text="Website")
    website_label.grid(row=2, column=0, padx=80)

    username_label = tk.Label(my_canvas, text="Username")
    username_label.grid(row=2, column=1, padx=80, pady=8)

    password_label = tk.Label(my_canvas, text="Password")
    password_label.grid(row=2, column=2, padx=80)

    days_password_is_good_for = tk.Label(my_canvas, text="Days password is good for")
    days_password_is_good_for.grid(row=2, column=3, padx=80)

I have tried following tutorials, however; they mostly seem to use the .pack method. I need to use the .grid method.


Solution

  • Note that widgets added into a canvas using .grid(...) will not be considered as canvas items, so the result of my_canvas.bbox("all") will not be affected.

    You need to create a frame and add it into the canvas using my_canvas.create_window(...), and then add those widgets into that frame. Also you need to bind <Configure> event on that frame and update the scrollregion of the canvas inside the event callback.

    Below is the modified code:

    import tkinter as tk
    
    window = tk.Tk()
    
    #window.geometry("1550x500")
    
    main_frame = tk.Frame(window, background="blue")
    main_frame.grid(sticky="news")
    
    my_canvas = tk.Canvas(main_frame)
    my_canvas.grid(row=0, column=9, sticky='news')
    
    # changed orientation to horizontal
    scrollbar = tk.Scrollbar(main_frame, orient="horizontal", command=my_canvas.xview)
    scrollbar.grid(row=1, column=9, sticky="ew")
    
    my_canvas.configure(xscrollcommand=scrollbar.set)
    
    def add_entry():
        pass
    
    # create a frame for other widgets
    my_frame = tk.Frame(my_canvas, bd=1, relief="solid")
    my_canvas.create_window(0, 0, window=my_frame, anchor="nw")
    
    vault_label = tk.Label(my_frame, text="Welcome to your password vault", font=("Time New Roman", 20))
    vault_label.grid(column=1, row=0)
    
    add_button = tk.Button(my_frame, text="Add new info", command=add_entry)
    add_button.grid(column=0, padx=8)
    
    website_label = tk.Label(my_frame, text="Website")
    website_label.grid(row=2, column=0, padx=80)
    
    username_label = tk.Label(my_frame, text="Username")
    username_label.grid(row=2, column=1, padx=80, pady=8)
    
    password_label = tk.Label(my_frame, text="Password")
    password_label.grid(row=2, column=2, padx=80)
    
    days_password_is_good_for = tk.Label(my_frame, text="Days password is good for")
    days_password_is_good_for.grid(row=2, column=3, padx=80)
    
    my_frame.bind('<Configure>', lambda e: my_canvas.configure(scrollregion=my_canvas.bbox("all")))
    
    window.mainloop()
    

    Result:

    enter image description here