[英]Slowing down Tkinter Canvas scrolling in Python
基本上,我可以运行以下代码,但是我找不到减慢画布视图拖动速度的方法,到目前为止,它的速度太快,无法对我的App起作用。 这只是一个小例子,显示了我要解决的问题:
from Tkinter import *
import Image, ImageTk
class GUI:
def __init__(self,root):
frame = Frame(root, bd=2, relief=SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
xscrollbar = Scrollbar(frame, orient=HORIZONTAL)
xscrollbar.grid(row=1, column=0, sticky=E+W)
yscrollbar = Scrollbar(frame)
yscrollbar.grid(row=0, column=1, sticky=N+S)
self.canvas = Canvas(frame, bd=0, xscrollcommand=xscrollbar.set, yscrollcommand=yscrollbar.set)
self.canvas.grid(row=0, column=0, sticky=N+S+E+W)
File = "JPG FILENAME HERE"
self.img = ImageTk.PhotoImage(Image.open(File))
self.canvas.create_image(0,0,image=self.img, anchor="nw")
self.canvas.config(scrollregion=self.canvas.bbox(ALL))
xscrollbar.config(command=self.canvas.xview)
yscrollbar.config(command=self.canvas.yview)
frame.pack()
self.canvas.bind("<Button 3>",self.grab)
self.canvas.bind("<B3-Motion>",self.drag)
def grab(self,event):
self._y = event.y
self._x = event.x
def drag(self,event):
if (self._y-event.y < 0): self.canvas.yview("scroll",-1,"units")
elif (self._y-event.y > 0): self.canvas.yview("scroll",1,"units")
if (self._x-event.x < 0): self.canvas.xview("scroll",-1,"units")
elif (self._x-event.x > 0): self.canvas.xview("scroll",1,"units")
self._x = event.x
self._y = event.y
root = Tk()
GUI(root)
root.mainloop()
回答:
布莱恩·奥克利(Bryan Oakley)的答案做了我刚刚改变的窍门:
self.canvas = Canvas(frame, bd=0, xscrollcommand=xscrollbar.set, yscrollcommand=yscrollbar.set)
至:
self.canvas = Canvas(frame, bd=0, xscrollcommand=xscrollbar.set, yscrollcommand=yscrollbar.set,xscrollincrement=10,yscrollincrement=10)
它就像一种魅力。
我真的不知道我在这里做什么,但这至少可以控制。 首先,显式设置画布大小:
self.canvas = Canvas(frame, bd=0, height=600, width=800,
xscrollcommand=self.xscrollbar.set,
yscrollcommand=self.yscrollbar.set)
然后,在__init__()
,添加几个实例变量来跟踪当前位置:
self.pos_x = self.pos_y = 0.0
然后,用以下方法替换drag
方法:
def drag(self, event):
# Note canvas dimensions are used here
self.pos_x += float(self._x-event.x) / 800.0
self.pos_y += float(self._y-event.y) / 600.0
if self.pos_x < 0.0: self.pos_x = 0.0
elif self.pos_x > 1.0: self.pos_x = 1.0
if self.pos_y < 0.0: self.pos_y = 0.0
elif self.pos_y > 1.0: self.pos_y = 1.0
self.canvas.xview("moveto", self.pos_x)
self.canvas.yview("moveto", self.pos_y)
self._x = event.x
self._y = event.y
我不知道为什么您必须强制转换这些数字才能浮动,但如果您不这样做,那将是行不通的。 它很脆; 如果将鼠标移动乘以任何值,甚至是0.99或1.01,该移动都会变得非常不稳定; 我怀疑鼠标移动和画布移动之间会发生某种反馈。 滚动条也不能很好地播放。 我想我们必须在移动pos_x和pos_y时更新它们。 就像我说的,真的不知道我在做什么。 我没有做太多的GUI编程。 无论如何,希望这会有所帮助。
尝试将画布的xscrollincrement
和yscrollincrement
属性的值设置为大于零的值。 这些设置对应的units
使用时,你调用xview
和yview
一个“单位”的说法(如: self.canvas.xview("scroll",-1,"units")
根据Tk的官方文档,如果这些值为零(默认值),则xview和yview会以[x,y] ScrollIncrement选项的单位(如果它大于零)或以-否则窗口的[宽度,高度]的十分之一”
尝试此操作,将拖动更改为仅使用计算值:
self.canvas.yview("scroll",self._y-event.y,"units")
self.canvas.xview("scroll",self._x-event.x,"units")
并将滚动增量更改为1。
现在,您的图像应该与鼠标光标同步单击并拖动,类似于流行的地图和文档查看器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.