tkinter:将鼠标滚轮绑定到滚动条

2024-04-27 02:32:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这个可滚动的框架(实际上是画布内的框架)

import Tkinter as tk
class Scrollbarframe():
    def __init__(self, parent,xsize,ysize,xcod,ycod):
        def ScrollAll(event):
                canvas1.configure(scrollregion=canvas1.bbox("all"),width=xsize,height=ysize,bg='white')
        self.parent=parent
        self.frame1=tk.Frame(parent,bg='white')
        self.frame1.place(x=xcod,y=ycod)
        canvas1=tk.Canvas(self.frame1)
        self.frame2=tk.Frame(canvas1,bg='white',relief='groove',bd=1,width=1230,height=430)
        scrollbar1=tk.Scrollbar(self.frame1,orient="vertical",command=canvas1.yview)
        canvas1.configure(yscrollcommand=scrollbar1.set)
        scrollbar1.pack(side="right",fill="y")
        canvas1.pack(side="left")
        canvas1.create_window((0,0),window=self.frame2,anchor='nw')
        self.frame2.bind("<Configure>",ScrollAll)

我想将鼠标滚轮绑定到滚动条上,这样用户就可以向下滚动框架,而不必使用滚动条上的箭头按钮。环顾四周之后,我向我的canvas1添加了一个绑定,如下所示

self.frame1.bind("<MouseWheel>", self.OnMouseWheel)

这就是功能:

def OnMouseWheel(self,event):
    self.scrollbar1.yview("scroll",event.delta,"units")
    return "break" 

但当我使用鼠标滚轮时,滚动条不会移动。有人能帮我吗?我想要的是当用户使用鼠标滚轮(在框架区域内/滚动条上)时,画布应该自动向上或向下滚动


Tags: self框架eventdef画布鼠标tkparent
3条回答

此链接提供了如何使用滚轮的示例

http://www.daniweb.com/software-development/python/code/217059/using-the-mouse-wheel-with-tkinter-python

我希望这有帮助

# explore the mouse wheel with the Tkinter GUI toolkit
# Windows and Linux generate different events
# tested with Python25
import Tkinter as tk
def mouse_wheel(event):
    global count
    # respond to Linux or Windows wheel event
    if event.num == 5 or event.delta == -120:
        count -= 1
    if event.num == 4 or event.delta == 120:
        count += 1
    label['text'] = count
count = 0
root = tk.Tk()
root.title('turn mouse wheel')
root['bg'] = 'darkgreen'
# with Windows OS
root.bind("<MouseWheel>", mouse_wheel)
# with Linux OS
root.bind("<Button-4>", mouse_wheel)
root.bind("<Button-5>", mouse_wheel)
label = tk.Label(root, font=('courier', 18, 'bold'), width=10)
label.pack(padx=40, pady=40)
root.mainloop()

也许最简单的解决方案是为鼠标滚轮创建全局绑定。然后,无论鼠标下是哪个小部件,或者哪个小部件具有键盘焦点,它都会触发。然后,您可以无条件地滚动画布,或者您可以聪明地确定哪些窗口应该滚动

例如,在windows上,您可以执行以下操作:

self.canvas = Canvas(...)
self.canvas.bind_all("<MouseWheel>", self._on_mousewheel)
...
def _on_mousewheel(self, event):
    self.canvas.yview_scroll(-1*(event.delta/120), "units")

请注意self.canvas.bind_all有点误导——您应该更正确地调用root.bind_all,但我不知道如何定义根窗口。无论如何,这两个调用是同义的

平台差异:

  • 在Windows上,您绑定到<MouseWheel>,需要将event.delta除以120(或其他一些因子,具体取决于您希望滚动的速度)
  • 在OSX上,您绑定到<MouseWheel>,并且需要不经修改地使用event.delta
  • 在X11系统上,您需要绑定到<Button-4><Button-5>,并且需要将event.delta除以120(或其他一些因子,具体取决于您希望滚动的速度)

还有更完善的解决方案涉及虚拟事件和确定哪个窗口具有焦点或在鼠标下,或者通过绑定传递画布窗口引用,但希望这能让您开始

根据@BryanOakley的回答,这里有一种只滚动聚焦小部件的方法(即当前鼠标光标所在的小部件)

绑定到画布内可滚动框架上发生的<Enter><Leave>事件,方法如下(scrollframe是画布内的框架):

    ...

    self.scrollframe.bind('<Enter>', self._bound_to_mousewheel)
    self.scrollframe.bind('<Leave>', self._unbound_to_mousewheel)

    return None

def _bound_to_mousewheel(self, event):
    self.canv.bind_all("<MouseWheel>", self._on_mousewheel)

def _unbound_to_mousewheel(self, event):
    self.canv.unbind_all("<MouseWheel>")

def _on_mousewheel(self, event):
    self.canv.yview_scroll(int(-1*(event.delta/120)), "units")

相关问题 更多 >