0

I am quite new to Tkinter and I had tried to create a program for multiple Tkinter Listbox that scrolls together using a single scrollbar and mouse wheel. When I run the program and start scrolling the left Listbox using my mouse wheel, the right Listbox doesn't scroll with it. However, when I start scrolling the right Listbox using the mouse wheel, the left Listbox scrolls with it. I couldn't find the error.

How do I fix the program so that when I start scrolling using my mouse wheel on either left or right Listbox, both Listbox will scroll together?

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()
DJ ShankyShoe
  • 39
  • 1
  • 5

1 Answers1

1

You can bind MouseWheel event to your root window which will allow you to scroll anywhere. If you don't want to bind to root window, you can also specify the widgets you want.

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()

For a more detailed explanation on why you need to do a delta/120, you can read up the answer here.

Henry Yik
  • 22,275
  • 4
  • 18
  • 40