Q:

Limiting Python Tkitner canvas scrollbar to only respond to mousewheel when full

I've written the tkinter code below such that the canvas can be scrolled by either the scrollbar or the mousewheel. The scrollbar works by default so that it is only enabled if the content is larger than the canvas, I would like to apply the same limitation to the mousewheel scrolling.
My code below produces a window where I can scroll through the buttons on the canvas. This is fine if there are 3 or more buttons but with 1 or 2, it can of course be scrolled anyway.
Any ideas? Thanks in advance.
from tkinter import *

root = Tk()
root.resizable(0, 0)

class Scroller():
    def __init__(self):
        self.scroll_canvas = Canvas(root, borderwidth=0, highlightthickness=0, height=200)
        self.scroll_frame = Frame(self.scroll_canvas, background="#ffffff")
        self.scroll_canvas.create_window(4, 4, window=self.scroll_frame)
        self.vsb = Scrollbar(root, orient="vertical", command=self.scroll_canvas.yview)
        self.scroll_canvas.configure(yscrollcommand=self.vsb.set)

        self.vsb.pack(side="right", fill="y")
        self.scroll_canvas.pack(side="left", fill='both', expand=True)

        self.scroll_frame.bind("<Configure>", self.scroll_configure)
        self.scroll_canvas.bind_all("<MouseWheel>", self.on_mousewheel)

    def on_mousewheel(self, event):
        if event.num == 5 or event.delta == -120:
            direction = 1
        if event.num == 4 or event.delta == 120:
            direction = -1
        self.scroll_canvas.yview_scroll(direction, "units")

    def scroll_configure(self, event):
        self.scroll_canvas.configure(scrollregion=self.scroll_canvas.bbox("all"))

buttons_frame = Frame(Scroller().scroll_frame, padx=5, pady=5)
buttons_frame.grid(row=1, column=1, sticky=N)

add_button = Button(buttons_frame, text='This\nis\na\nbutton.\nAdd Another Button',
                    command=lambda: add_another_button())
add_button.pack()

def add_another_button():
    Button(buttons_frame, text='This\nis\na\nbutton.\nAdd Another Button', command=lambda: add_another_button()).pack()

root.mainloop()

A:

As far as I can see you're not able to check how many buttons already have been added, is this correct? I think in your current configuration it's not possible to decide whether to scroll or not.
My approach would be to register how many buttons (or how much vertical space) you've already used (update that when a new button is added), and then compare that in on_mousewheel to the window size and decide if yview_scroll() is triggered or not.

