TeaCoast
TeaCoast

Reputation: 434

How to use the mouse wheel to scroll in Tkinter, if it's in the frame the scrollbar is in?

I know that there is .bind and .bind_all methods, but there are problems with both of them. If you use .bind, it will only scroll if your cursor is in the empty space of that frame. If you use .bind_all, anywhere your mouse is, it will scroll if you use the mouse wheel. Is there a way to scroll it with the mouse wheel only when the cursor is in a certain frame?

Upvotes: 2

Views: 4392

Answers (1)

Saad
Saad

Reputation: 3430

You can use <Enter> and <Leave> binds of that widget to handle when the widget should have mouse wheel scrolling.

By using bind_all with <MouseWheel> sequence only when the cursor is moved onto that widget which can be checked with <Enter> sequence bind and unbinding the <MouseWheel> when the cursor is moved away from the widget.

Have a look at this example.

import tkinter as tk


def set_mousewheel(widget, command):
    """Activate / deactivate mousewheel scrolling when 
    cursor is over / not over the widget respectively."""
    widget.bind("<Enter>", lambda _: widget.bind_all('<MouseWheel>', command))
    widget.bind("<Leave>", lambda _: widget.unbind_all('<MouseWheel>'))


root = tk.Tk()
root.geometry('300x300')

l0 = tk.Label(root, text='Hover and scroll on the labels.')
l0.pack(padx=10, pady=10)

l1 = tk.Label(root, text='0', bg='pink', width=10, height=5)
l1.pack(pady=10)
set_mousewheel(l1, lambda e: l1.config(text=e.delta))

l2 = tk.Label(root, text='0', bg='cyan', width=10, height=5)
l2.pack(pady=10)
set_mousewheel(l2, lambda e: l2.config(text=e.delta))

root.mainloop()

This example works every well with a Scrollable frame created with canvas, as the main frame inside canvas has multiple widgets and if we don't use bind_all over bind then the scrolling will not work if the cursor moves over the widget inside that scrollable frame.

Upvotes: 8

Related Questions