使用鼠标滚轮和滚动条一起滚动多个 Tkinter 列表框

Scrolling multiple Tkinter listboxes together using mouse wheel and scrollbar

我对 Tkinter 很陌生,我曾尝试为多个 Tkinter 列表框创建一个程序,该程序使用单个滚动条和鼠标滚轮一起滚动。当我 运行 程序并开始使用鼠标滚轮滚动左侧列表框时,右侧列表框不会随之滚动。但是,当我开始使用鼠标滚轮滚动右侧列表框时,左侧列表框会随之滚动。我找不到错误。

如何修复程序,以便当我开始使用鼠标滚轮在左侧或右侧列表框上滚动时,两个列表框会一起滚动?

try:
    from Tkinter import *
except ImportError:
    from tkinter import *


class MultipleScrollingListbox(Tk):

    def __init__(self):
        Tk.__init__(self)
        self.title('Scrolling Multiple Listboxes')

        self.scrollbar = Scrollbar(self, orient='vertical')

        self.list1 = Listbox(self, width = 40, height = 10, yscrollcommand = self.yscroll1)
        self.list1.grid(row = 2, sticky = W)

        self.list2 = Listbox(self, width = 40, height = 10, yscrollcommand = self.yscroll1)
        self.list2.grid(row = 2, column = 1, sticky = E)

        self.scrollbar.config(command=self.yview)
        self.scrollbar.grid(row = 2, column = 2, sticky = "nsw")

        #filling the listboxes with stuff

        for x in range(30):
            self.list1.insert('end', "  " + str(x))
            self.list2.insert('end', "  " + str(x))


    #The part where both Listbox scrolls together when scrolled 

    def yscroll1(self, *args):
        if self.list2.yview() != self.list1.yview():
            self.list2.yview_moveto(args[0])
        self.scrollbar.set(*args)

    def yscroll2(self, *args):
        if self.list1.yview() != self.list2.yview():
            self.list1.yview_moveto(args[0])
        self.scrollbar.set(*args)

    def yview(self, *args):
        self.list1.yview(*args)
        self.list2.yview(*args)


if __name__ == "__main__":
    root = MultipleScrollingListbox()
    root.mainloop()

您可以将 MouseWheel 事件绑定到您的根 window,这样您就可以在任何地方滚动。如果你不想绑定到 root window,你也可以指定你想要的小部件。

try:
    from Tkinter import *
except ImportError:
    from tkinter import *


class MultipleScrollingListbox(Tk):

    def __init__(self):
        Tk.__init__(self)

        ... 

        self.bind_all("<MouseWheel>", self.mousewheel)

        ...

    def mousewheel(self, event):
        self.list1.yview_scroll(-1 * int(event.delta / 120), "units")
        self.list2.yview_scroll(-1 * int(event.delta / 120), "units")

if __name__ == "__main__":
    root = MultipleScrollingListbox()
    root.mainloop()

有关为什么需要执行 delta/120 的更详细解释,您可以阅读答案 here