Python Tkinter-使用鼠标位置滚动画布 [英] Python Tkinter - canvas scrolling with mouse position

查看:506
本文介绍了Python Tkinter-使用鼠标位置滚动画布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为这是一个非常普遍的问题,但我找不到答案.

I think this is a very common question, but I couldn't find the answer.

我正在尝试创建一个根据鼠标位置滚动的窗口:如果鼠标靠近屏幕顶部,则滚动至顶部;如果鼠标靠近屏幕右边框,则滚动至右侧等等.这是代码:

I'm trying to make a window that scrolls depending on the mouse position: if the mouse is close to top of the screen, it scrolls to the top, if it is close to the right border, it scrolls to the right and so on. Here is the code:

from tkinter import *
from tkinter import ttk
root = Tk()

h = ttk.Scrollbar(root, orient = HORIZONTAL)
v = ttk.Scrollbar(root, orient = VERTICAL)
canvas = Canvas(root, scrollregion = (0, 0, 2000, 2000), width = 600, height = 600, yscrollcommand = v.set, xscrollcommand = h.set)
h['command'] = canvas.xview
v['command'] = canvas.yview
ttk.Sizegrip(root).grid(column=1, row=1, sticky=(S,E))

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)

canvas.create_rectangle((0, 0, 50, 50), fill = 'black')
canvas.create_rectangle((500, 500, 550, 550), fill = 'black')
canvas.create_rectangle((1500, 1500, 1550, 1550), fill = 'black')
canvas.create_rectangle((1000, 1000, 1050, 1050), fill = 'black')

def xy_motion(event):
    x, y = event.x, event.y

    if x < 30:        
        delta = -1
        canvas.xview('scroll', delta, 'units')

    if x > (600 - 30):
        delta = 1
        canvas.xview('scroll', delta, 'units')

    if y < 30:
        delta = -1
        canvas.yview('scroll', delta, 'units')

    if y > (600 - 30):
        delta = 1
        canvas.yview('scroll', delta, 'units')

canvas.bind('<Motion>', xy_motion)

root.mainloop()

问题在于滚动运动位于仅在有鼠标移动的情况下才起作用的运动功能(如果停止移动鼠标,滚动也将停止).我想提出一种方式,即使鼠标不移动(但仍在滚动区域"中),窗口也将一直滚动直到到达终点为止.

The problem is that the scrolling movement is in the motion function that only works if there is mouse movement (if you stop moving the mouse, the scrolling stops too). I would like to make it a way that even if the mouse is not moving (but still in the "scrolling area") the window would keep scrolling until it reaches the end.

我认为显而易见的方法是将if语句(例如,从第30行)更改为while语句,如下所示:

I thought the obvious way would be changing the if statement (from line 30 for example) to a while statement, like this:

while x < 30:

但是,当鼠标到达此位置时,程序冻结(我认为等待while循环结束).

But then when the mouse reaches this position the program freezes (waiting for the while loop to finish I think).

有什么建议吗?

谢谢.

更新

这是带有一个(或一个可能的)答案的有效代码.我不知道用答案来更新问题本身是否合适,但我认为这对其他人可能有用.

Here is the working code with an (or one of the possible) answer. I don't know if it is right to update the question itself with the answer, but I think it can be useful to others.

x, y = 0, 0

def scroll():
    global x, y

    if x < 30:
        delta = - 1
        canvas.xview('scroll', delta, 'units')

    elif x > (ws - 30):
        delta = 1
        canvas.xview('scroll', delta, 'units')

    elif y < 30:
        delta = -1
        canvas.yview('scroll', delta, 'units')

    elif y > (ws - 30):
        delta = 1
        canvas.yview('scroll', delta, 'units')

    canvas.after(100, scroll)

def xy_motion(event):
    global x, y
    x, y = event.x, event.y

scroll()

canvas.bind('<Motion>', xy_motion)

请让我知道是否正确.感谢大家的讨论和建议. 这些

Please let me know if it is correct. Thanks to everyone for the discussion and suggestions. These links were useful too.

推荐答案

首先,设置一种方法,该方法以很小的量滚动窗口,然后在一定的固定时间段(例如100ms)之后再次调用自身(如果鼠标是在该区域.您可以使用之后"方法来执行此操作.这样,只要鼠标位于滚动区域中,画布就会连续滚动.

First, set up a method that scrolls the window by a tiny amount, then calls itself again after some fixed period of time (eg 100ms) if the mouse is in the region. You can use the method "after" todo this. With this, the canvas will continuously scroll as long as the mouse is in the scroll region.

接下来,创建一个绑定,当光标第一次进入滚动区域时,将调用此函数.

Next, create a binding that calls this function when the cursor enters the scroll zone for the first time.

这就是您所需要的.只要确保您一次只能运行一个tbese滚动作业即可.

And that's all you need. Just make sure you only have one of tbese scroll jobs running at any one time.

这篇关于Python Tkinter-使用鼠标位置滚动画布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆