如何在tkinter Listbox中的yscrollcommand中传递参数到lambda函数? &



列表框对象是在app类的for循环中生成的。它的yscrollcommand, 6个函数是硬编码的。(def function for 0, def function for 1…)

如果我可以传递index参数给lambda函数,列表滚动的6个功能可以压缩为1个for loop。

但是在类中的函数,它有参数'self'。它使我迷惑。

我如何通过索引参数lambda函数在yscrollcommand?

class app(tk.Frame):
def __init__(self):
self.root = tk.Tk()
self.root.title('title something')
# showing data frame
self.data_frame = tk.LabelFrame(self.root, text='')
self.data_frame.pack(fill='x')

self.scrollbar = tk.Scrollbar(self.data_frame)
self.scrollbar.pack(side='right', fill='y')

self.listboxes = []
self.listboxes_column = 6 # This can be vary.

# listboxes are in a list.
for i in range(self.listboxes_column):
self.listboxes.append(tk.Listbox(self.data_frame, selectmode='extended', height=20, width=0, yscrollcommand = self.scrollbar.set))
self.listboxes[i].pack(side='left')

# when self.listboxes_column == 3
# self.list_indexes == [[1, 2, 3], [0, 2, 3], [0, 1, 3], [0, 1, 2]]
self.list_indexes = []
for i in range(self.listboxes_column):
indexes = [j for j in range(self.listboxes_column)]
indexes.remove(i)
self.list_indexes.append(indexes)
# a listbox can scroll the others     
# with lambda function and argument passing,
# I want to make these 6 lines be in a for loop.
# The from like this
# for i in range(6):
#     self.listboxes[index_argument].config(yscrollcommand = lambda ????? : self.list_scrolls_all(index_argument  ????? ))
self.listboxes[0].config(yscrollcommand = self.list0_scrolls_all)
self.listboxes[1].config(yscrollcommand = self.list1_scrolls_all)
self.listboxes[2].config(yscrollcommand = self.list2_scrolls_all)
self.listboxes[3].config(yscrollcommand = self.list3_scrolls_all)
self.listboxes[4].config(yscrollcommand = self.list4_scrolls_all)
self.listboxes[5].config(yscrollcommand = self.list4_scrolls_all)

self.scrollbar.config(command=self.bar_scrolls_all)
self.root.mainloop()

# functions for lists scroll from 0 to 5.
# I don't know how to pass argument via yscrollcommand in Listbox.
# I want a form like this.
#
# def list_scrolls_all(self, index, *args):
#     for i in self.list_indexes[index] :
#         self.listboxes[i].yview_moveto(args[0])
#     self.scrollbar.set(*args)
def list0_scrolls_all(self, *args):
for i in self.list_indexes[0] :
self.listboxes[i].yview_moveto(args[0])
self.scrollbar.set(*args)
def list1_scrolls_all(self, *args):
for i in self.list_indexes[1] :
self.listboxes[i].yview_moveto(args[0])
self.scrollbar.set(*args)

# scroll bar
def bar_scrolls_all(self,*args):
for i in range(self.listboxes_column):
self.listboxes[i].yview(*args)

我只是碰巧在一个多列表框程序上工作,所以我对你的代码做了一些修改。

我已经包含了flexx函数,所以所有的对象都是完全灵活的,尽管我不得不用grid代替pack

import tkinter as tk
def flexx(m, r = 0, c = 0, rw = 1, cw = 1):
if r !=  None:
m.rowconfigure(r, weight = rw)
if c !=  None:
m.columnconfigure(c, weight = cw)
class app:
def __init__(self):
self.root = tk.Tk()
self.root.title('title something')
# make root flexible
flexx(self.root)
# showing data frame
self.data_frame = tk.LabelFrame(self.root, text='Multiple Linked Listboxes')
self.data_frame.grid(row = 0, column = 0, sticky = tk.NSEW)
self.listboxes = []
self.listboxes_column = 6 # This can be vary.
self.scrollbar = tk.Scrollbar(self.data_frame)
self.scrollbar.grid(row = 0, column = self.listboxes_column, sticky = tk.NS)
# listboxes are in a list.
for i in range(self.listboxes_column):
self.listboxes.append(tk.Listbox(
self.data_frame, selectmode='extended',
height=20, width=0))
self.listboxes[i].grid(row = 0, column = i, sticky = tk.NSEW)
# make data_frame flexible
flexx(self.data_frame, c = i)
# populate listbox with some data for testing purposes
for b in dir(self):
self.listboxes[i].insert("end", b)
# connect yscollcommand to all listboxes
for a in self.listboxes:
a["yscrollcommand"] = self.move_to
if False: # Not sure waht this does
# when self.listboxes_column == 3
# self.list_indexes == [[1, 2, 3], [0, 2, 3], [0, 1, 3], [0, 1, 2]]
self.list_indexes = []
for i in range(self.listboxes_column):
indexes = [j for j in range(self.listboxes_column)]
indexes.remove(i)
self.list_indexes.append(indexes)
# connect scrollbar command to all y_views
self.scrollbar.config(command = self.y_view)
def y_view(self, *args):
for a in self.listboxes:
a.yview(*args)
def move_to(self, *args):
self.scrollbar.set(*args)
self.y_view("moveto", args[0])
if __name__ == "__main__":
demo = app()
demo.root.mainloop()

最新更新