为什么Python Tkinter Canvas不滚动?

时间:2015-10-28 20:22:28

标签: python macos tkinter magic-mouse

为什么我不能让python tkinter画布响应Apple的Magic Mouse鼠标的垂直和水平滑动/滚动?画布的滚动条正常工作(意味着当我在鼠标上水平滑动/滚动时水平条工作但在我垂直滑动/滚动时不工作,垂直滚动条在我垂直滑动/滚动但不响应任何水平时移动滑动/滚动动画),但画布不会对任何滑动/滚动鼠标做出反应。

这是我的示例/测试代码:

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()

对于Python和tkinter来说,我都是新手,但我觉得这应该是非常简单明了(或者至少可行)。然而,我看了一遍,仍然无法找到答案(虽然我可能会使用错误的术语进行搜索)。

如果滚动条已经存在,画布会对Magic Mouse的滚动/滑动输入作出什么反应?

编辑:我使用的是Python 3.4,Tkinter 8.5.18,Mac OS X 10.9.5和Apple Magic Mouse

2 个答案:

答案 0 :(得分:2)

假设魔术鼠标的滚动和滑动输入与标准触控板上的滚动区域类似,则需要绑定<MouseWheel><Shift-MouseWheel>事件。

首先是代码,然后是一些注释。

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()

正如您所看到的,只有2个变化。

  1. 有两个回调函数可以处理滚动事件on_verticalon_horizontal
  2. 广告素材<MouseWheel><Shift-MouseWheel>事件分别与on_verticalon_horizontal绑定。

答案 1 :(得分:0)

使用 ntk Canvas 创建一个可滚动的 Canvas,默认情况下它适用于鼠标滚动,但如果您创建一个 ntk Scrollbar 小部件,并将其分配给 canvas,您就可以开始了。

ntk 在 tkinter 之上工作,使用 pip 从 pypi 安装它

pip install ntk

使用 ntk 小部件获得出色的设计。

from ntk import Tk, Canvas, Scrollbar

def main():
    root = Tk()

canvas = Canvas(root)

    root.mainloop()    

if __name__=='__main__':
    main()

这个画布可以通过鼠标滚动来滚动,但是如果你想用它设置一个栏,你可以创建一个滚动条小部件并将这个画布对象作为第二个参数传递

scroll = Scrollbar(root, canvas)

您可以通过配置或在创建画布时传递它来更改画布中的可滚动区域

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

或通过配置

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

欢迎使用更少代码的漂亮设计,快乐编码。