Why won't the Python Tkinter Canvas Scroll?

五迷三道 提交于 2021-02-19 04:05:59

问题


Why can't I get the python tkinter canvas to respond to the vertical and horizontal swiping/scrolling of Apple's Magic Mouse? The scrollbars for the canvas work properly (meaning the horizontal bar works when I swipe/scroll horizontally on the mouse but not when I swipe/scroll vertically, and the vertical scrollbar moves when I swipe/scroll vertically but doesn't react to any horizontal swiping/scrolling motion), but the canvas doesn't react to any swiping/scrolling of the mouse.

Here is my example/test code:

from tkinter import *
import tkinter.ttk as ttk
from PIL import Image, ImageTk
root = Tk()

h = Scrollbar(root, orient=HORIZONTAL)
v = Scrollbar(root, orient=VERTICAL)
canvas = Canvas(root, scrollregion=(0, 0, 1000, 1000), yscrollcommand=v.set, xscrollcommand=h.set)
h['command'] = canvas.xview
v['command'] = canvas.yview
theImage = ImageTk.PhotoImage(Image.open('example.png')) #Assume a very large image
canvas.create_image(0,0,image=theImage, anchor='nw')
canvas.grid(column=0, row=0, sticky=(N,W,E,S))
h.grid(column=0, row=1, sticky=(W,E))
v.grid(column=1, row=0, sticky=(N,S))
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
root.mainloop()

I'm a total novice when it comes to both Python and tkinter, but I feel like this should be really simple and obvious (or at least do-able). And yet I've looked all over and still can't find the answer (though I might be searching using the wrong jargon).

What does it take to make the canvas react to scrolling/swiping inputs from the Magic Mouse like the scrollbars do already?

Edit: I'm using Python 3.4, Tkinter 8.5.18, Mac OS X 10.9.5, and an Apple Magic Mouse


回答1:


Assuming that the magic mouse's scroll and swipe inputs work like the scrolling regions on a standard trackpad, you need to bind the <MouseWheel> and <Shift-MouseWheel> events.

First the code, then some notes.

from tkinter import *
import tkinter.ttk as ttk
from PIL import Image, ImageTk

def on_vertical(event):
    canvas.yview_scroll(-1 * event.delta, 'units')

def on_horizontal(event):
    canvas.xview_scroll(-1 * event.delta, 'units')

root = Tk()
h = Scrollbar(root, orient=HORIZONTAL)
v = Scrollbar(root, orient=VERTICAL)
canvas = Canvas(root, scrollregion=(0, 0, 1000, 1000), yscrollcommand=v.set, xscrollcommand=h.set)
h['command'] = canvas.xview
v['command'] = canvas.yview
theImage = ImageTk.PhotoImage(Image.open('img'))
canvas.create_image(0,0,image=theImage, anchor='nw')
canvas.grid(column=0, row=0, sticky=(N,W,E,S))

canvas.bind_all('<MouseWheel>', on_vertical)
canvas.bind_all('<Shift-MouseWheel>', on_horizontal)

h.grid(column=0, row=1, sticky=(W,E))
v.grid(column=1, row=0, sticky=(N,S))
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
root.mainloop()

As you can see there are only 2 changes.

  1. There are two callback functions to handle the scroll events on_vertical and on_horizontal
  2. The canvas <MouseWheel> and <Shift-MouseWheel> events are bound to on_vertical and on_horizontal respectively.



回答2:


Use ntk Canvas to create a scroll able Canvas, by default it works on mouse scroll, but if you create a ntk Scrollbar widget, and assign it to canvas, you are good to go.

ntk works on top of tkinter, to install it from pypi with pip

pip install ntk

use ntk widgets to get awesome design.

from ntk import Tk, Canvas, Scrollbar

def main():
    root = Tk()

canvas = Canvas(root)

    root.mainloop()    

if __name__=='__main__':
    main()

this canvas is scroll able by mouse scroll, but if you want to set a bar with it, you can create a scroll bar widget and pass this canvas object as second param

scroll = Scrollbar(root, canvas)

you can change scroll able area from canvas by configure or pass it when canvas is creating

canvas = Canvas(root, scrollregion=[0,0,100,50]) # [x1, y1, x2, y2]

or configure it by

canvas.config(scrollregion=[0,0,100,50])

welcome to beautiful design in less code, happy codding.



来源:https://stackoverflow.com/questions/33400918/why-wont-the-python-tkinter-canvas-scroll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!