用一个滚动条滚动两个不同长度的列表框

Scrolling two listboxes of different lengths with one scrollbar

我在将 Tkinter 滚动条与两个列表框小部件同步时遇到了一个小问题。当两个列表框中的内容不相同时,否则我会遇到此错误,如果长度相同则没有问题。下面是我的短代码:

try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

class App(object):
    def __init__(self,master):
        scrollbar = tk.Scrollbar(master, orient='vertical')
        self.lb1 = tk.Listbox(master, yscrollcommand=scrollbar.set)
        self.lb2 = tk.Listbox(master, yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.yview)
        scrollbar.pack(side='right', fill='y')
        self.lb1.pack(side='left', fill='both', expand=True)
        self.lb2.pack(side='left', fill='both', expand=True)

    def yview(self, *args):
        """connect the yview action together"""
        self.lb1.yview(*args)
        self.lb2.yview(*args)


root = tk.Tk()
# use width x height + x_offset + y_offset (no spaces!)
root.geometry("320x180+130+180")
root.title("connect 2 listboxes to one scrollbar")

app = App(root)

# load the list boxes for the test
for n in range(64+26, 64, -1): #listbox 1
    app.lb1.insert(0, chr(n)+'ell')

for n in range(70+30, 64, -1):    
    app.lb2.insert(0, chr(n)+'ell') #listbox 2

root.mainloop()

我想要的

我知道错误很明显,因为两个列表的长度不匹配。我想要的是 运行 上面的代码,滚动条应该按照两个列表中给出的顺序从第一个词即 Aell 到最后一个词 Zell 右同步。

我认为的方法是始终根据最短列表的长度滚动两个列表(在我的例子中是左侧列表),这样我至少可以匹配所有可能的点。

最后,我只有在上下拖动滑块进行滚动时才会遇到此错误。但是当我只是暂时按下并释放滚动条上的向上和向下箭头时,一切正常。

我试过的

除了在线阅读之外,我也尝试通过以下方式引入事件和绑定,希望能够限制滚动步长,但没有改变。

self.lb1.bind('<Up>', lambda event: self.scroll_listboxes(-1))
self.lb2.bind('<Up>', lambda event: self.scroll_listboxes(-1))
self.lb1.bind('<Down>', lambda event: self.scroll_listboxes(1))
self.lb2.bind('<Down>', lambda event: self.scroll_listboxes(1))

def scroll_listboxes(self, yFactor):
#function runs when a listbox has focus and the Up or Down arrow 
#keys are pressed
    self.listbox1.yview_scroll(yFactor, "units")
    self.listbox2.yview_scroll(yFactor, "units")

P.S.

我刚刚想到了一些事情,但真的不确定这是否完全正确。由于长度不匹配,因此两个列表框的滚动动作各不相同。那么是否有可能以某种方式强制另一个列表上的最短列表的滚动操作?这样,另一个包含更多内容的列表将无法自由移动,并且必须像最短的内容列表框一样遵循滚动模式。

最简单的解决方案是在较短的列表中简单地添加足够多的空白行,使其具有与较长列表完全相同的元素数量。

您在评论中提到您认为这样做效率低下,但我认为情况并非如此,除非您在一个列表中的项目比另一个列表中的项目多出数万个。