0

As you can see in the picture I want the canvas scrollbar to go all the way right... In a few words I want the canvas to cover all the red bg that the frame 2 has... Any ideas? Here is the code: (reference to the code bellow about the scrollbar code you will find here)

upFrame = Frame(window, bg='lightgray')
upFrame.grid(row=1, column=0, sticky='nesw')
midFrame = Frame(window, bg='red')
midFrame.grid(row=2, column=0, sticky='nesw')
bottomFrame = Frame(window, bg='lightgray')
bottomFrame.grid(row=3, column=0, sticky='nesw')
    
    
window.grid_rowconfigure(1, weight = 0)
window.grid_columnconfigure(0, weight = 1)
window.grid_rowconfigure(1, weight = 0)

container = Frame(midFrame)
canvas = Canvas(container)
scrollbar = Scrollbar(container, orient="vertical", command=canvas.yview)
scrollable_frame = Frame(canvas)

scrollable_frame.bind(
    "<Configure>",
     lambda e: canvas.configure(
      scrollregion=canvas.bbox("all")
     )
  )
    
canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")

canvas.configure(yscrollcommand=scrollbar.set)
    
for i in range(50):
    Label(scrollable_frame, text="Sample scrolling label").pack()

container.grid(row=2, column=0, sticky='nesw')
canvas.pack(side='left', fill='both', expand=True)
scrollbar.pack(side="right", fill="y")

layout

Also It would be helpfull if you guys could tell me how to make the scrollbar move with the mouse wheel

Thomas
  • 37
  • 6

1 Answers1

1

Next time please add a complete reproducible example including the imports and mainloop so it is easier to follow.

Make your canvas scrollable

(source: tkinter: binding mousewheel to scrollbar):

# bind scrolling to mousewheel
def _scroll_canvas(event):
    canvas.yview_scroll(-1*(int(event.delta/100)), "units")
canvas.bind_all("<MouseWheel>", _scroll_canvas)

Stick your scrollbar on the right side

  1. You dont need another frame just for the Canvas, i removed your container Frame and put the Canvas directly into your midFrame. The red background can be removed also.
  2. Same goes for your scrollbar - put directly into your midFrame
  3. For the red portion i created a new sub-frame called red_frame (at the bottom)
  4. If you want the scrollbar to appear on the right side of the screen, use pack with the "right" option, and for all other sub-frames use the "left" option. Everything else is managed by the order in which you pack the widgets.

Full code:

from tkinter import Frame, Canvas, Scrollbar, Tk, Label

window = Tk()

upFrame = Frame(window, bg='lightgray')
upFrame.grid(row=1, column=0, sticky='nesw')
midFrame = Frame(window, bg='red')
midFrame.grid(row=2, column=0, sticky='nesw')
bottomFrame = Frame(window, bg='lightgray')
bottomFrame.grid(row=3, column=0, sticky='nesw')
    
    
window.grid_rowconfigure(1, weight = 0)
window.grid_columnconfigure(0, weight = 1)
window.grid_rowconfigure(1, weight = 0)

canvas = Canvas(midFrame)
scrollbar = Scrollbar(midFrame, orient="vertical", command=canvas.yview)
scrollable_frame = Frame(canvas)

scrollable_frame.bind(
    "<Configure>",
     lambda e: canvas.configure(
      scrollregion=canvas.bbox("all")
     )
  )
    
canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")

canvas.configure(yscrollcommand=scrollbar.set)

# bind scrolling to mousewheel
def _scroll_canvas(event):
    canvas.yview_scroll(-1*(int(event.delta/100)), "units")
canvas.bind_all("<MouseWheel>", _scroll_canvas)
    
for i in range(50):
    Label(scrollable_frame, text="Sample scrolling label").pack()

# here you decide in which order your widgets appear: canvas, red frame and on the right - your scrollbar
canvas.pack(side='left', fill='both')
red_frame = Frame(midFrame, bg="red")
red_frame.pack(side="left")
scrollbar.pack(side="right", fill="y")

window.mainloop()
mnikley
  • 1,625
  • 1
  • 8
  • 21
  • Thank you very much! That one fixed my problem... Also the red_frame i don't quite unterstand why you kept it... I had it there because I wanted to see if the canvas will cover it, that's the only reason why I kept it there... – Thomas Dec 23 '21 at 09:26
  • 1
    @Thomas Ah, makes sense. Somehow i thought it was part of your UI, but you can simply remove it then :) Glad i could help – mnikley Dec 23 '21 at 09:35