简体   繁体   中英

trouble with mousewheel + scrollbars in tkinter

i am trying to display images using tkinter and i have trouble when adding a scrollbar. I would like to be able to scroll with the mousewheel both horizontally and vertically, should the image exceed the windowsize. The problem is that the mousewheel does not work when i use a canvas.

in this code i can use mousewheel to scroll Y and shift+mousewheel to scroll X (which is exactly what i want):

import tkinter as tk

master = tk.Tk()

scrollbarX = tk.Scrollbar(master)
scrollbarX.pack(side=tk.BOTTOM, fill=tk.X)
scrollbarY = tk.Scrollbar(master)
scrollbarY.pack(side=tk.RIGHT, fill=tk.Y)

listbox = tk.Listbox(master, yscrollcommand=scrollbarY.set, xscrollcommand=scrollbarX.set)

for i in range(1000):
    listbox.insert(tk.END, str(i)+"-----------------------------------------------------------------------")

listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=tk.YES)

scrollbarX.config(command=listbox.xview, orient=tk.HORIZONTAL)
scrollbarY.config(command=listbox.yview)

master.mainloop()

However, if i exchange the listbox with a canvas, the mouswheel does not do anything anymore. Scrolling manually still works:

import tkinter as tk
from PIL import Image, ImageTk

master = tk.Tk()

scrollbarX = tk.Scrollbar(master)
scrollbarX.pack(side=tk.BOTTOM, fill=tk.X)
scrollbarY = tk.Scrollbar(master)
scrollbarY.pack(side=tk.RIGHT, fill=tk.Y)

canvas = tk.Canvas(master, bd=0, xscrollcommand=scrollbarX.set, yscrollcommand=scrollbarY.set)

imagefile = "image.png"
img = ImageTk.PhotoImage(Image.open(imagefile))
canvas.create_image(0,0,image=img, anchor="nw")

canvas.pack(fill=tk.BOTH, expand=tk.YES)

scrollbarX.config(command=canvas.xview, orient=tk.HORIZONTAL)
scrollbarY.config(command=canvas.yview)

canvas.config(scrollregion=canvas.bbox(tk.ALL))

master.mainloop()

I am still new to programming, any help is greatly appreciated!

You need to handle the mouse events and do the scrolling.

You can do that by having a callback like this:

def on_mousewheel(event):
    shift = (event.state & 0x1) != 0
    scroll = -1 if event.delta > 0 else 1
    if shift:
        canvas.xview_scroll(scroll, "units")
    else:
        canvas.yview_scroll(scroll, "units")

Then you bind it to canvas like this:

canvas.bind_all("<MouseWheel>", on_mousewheel)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM