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

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

Asked 1 years ago
5
3 answers

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.

Source: link

0

# explore the mouse wheel with the Tkinter GUI toolkit
# Windows and Linux generate different events
# tested with Python25

import Tkinter as tk

def mouse_wheel(event):
    global count
    # respond to Linux or Windows wheel event
    if event.num == 5 or event.delta == -120:
        count -= 1
    if event.num == 4 or event.delta == 120:
        count += 1
    label['text'] = count

count = 0
root = tk.Tk()
root.title('turn mouse wheel')
root['bg'] = 'darkgreen'

# with Windows OS
root.bind("<MouseWheel>", mouse_wheel)
# with Linux OS
root.bind("<Button-4>", mouse_wheel)
root.bind("<Button-5>", mouse_wheel)

label = tk.Label(root, font=('courier', 18, 'bold'), width=10)
label.pack(padx=40, pady=40)

root.mainloop()

Source: link

0

class ScrollFrame(tk.Frame): def init(self): super().init() # create a frame (self)
self.canvas = tk.Canvas(self, borderwidth=0, background="#000000")          #place canvas on self
    self.viewPort = tk.Frame(self.canvas, background="#000000")                    #place a frame on the canvas, this frame will hold the child widgets
    self.vsb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview) #place a scrollbar on self
    self.hsb = tk.Scrollbar(self, orient=HORIZONTAL, command=self.canvas.xview)  # place a scrollbar on self
    self.canvas.configure(yscrollcommand=self.vsb.set,xscrollcommand=self.hsb.set)                          #attach scrollbar action to scroll of canvas
    #self.canvas.configure(xscrollcommand=self.hsb.set)
    self.vsb.pack(side="right", fill="y")                                       #pack scrollbar to right of self
    self.hsb.pack(side="bottom", fill=X)
    self.canvas.pack(side="right", fill="both", expand=True)                     #pack canvas to left of self and expand to fil
    self.canvas_window = self.canvas.create_window((0,0), window=self.viewPort, anchor="nw",            #add view port frame to canvas
                              tags="self.viewPort")

    self.viewPort.bind("<Configure>", self.onFrameConfigure)                       #bind an event whenever the size of the viewPort frame changes.
    self.canvas.bind("<Configure>", self.onCanvasConfigure)                       #bind an event whenever the size of the viewPort frame changes.

    self.onFrameConfigure(None)                                                 #perform an initial stretch on render, otherwise the scroll region has a tiny border until the first resize

def onFrameConfigure(self, event):
    '''Reset the scroll region to encompass the inner frame'''
    self.canvas.configure(scrollregion=self.canvas.bbox("all"))                 #whenever the size of the frame changes, alter the scroll region respectively.

def onCanvasConfigure(self, event):
    '''Reset the canvas window to encompass inner frame when required'''
    canvas_width = event.width
    self.canvas.itemconfig(self.canvas_window, width = canvas_width)            #whenever the size of the canvas chang
from tkinter import ttk
style = ttk.Style()
style.theme_use('clam')

...
self.vsb = ttk.Scrollbar(self, orient="vertical", command=self.canvas.yview) #place a scrollbar on self

Source: link

Recent Questions on python

    Programming Languages