我在使用两个列表框小部件同步我的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。
我只是想到了什么,但我真的不确定这是否一直都是正确的。由于长度不匹配,因此两个列表框的滚动操作都不同。那么有可能以某种方式强制最短列表的滚动动作在另一个列表上吗?这样,具有更多内容的另一个列表将无法自由移动,并且必须遵循滚动模式,就像最短的内容列表框一样。
答案 0 :(得分:2)
最简单的解决方案是简单地在较短的列表中添加足够的空白行,以便它与较长的列表具有完全相同的元素数。
您在评论中提到您认为效率低下,但我不认为情况如此,除非您在一个列表中拥有的数量多于另一个列表中的数万个。