繁体   English   中英

减慢Python中的Tkinter画布滚动

[英]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编程。 无论如何,希望这会有所帮助。

尝试将画布的xscrollincrementyscrollincrement属性的值设置为大于零的值。 这些设置对应的units使用时,你调用xviewyview一个“单位”的说法(如: 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.

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