【问题标题】:Which dynamically created object called the function?哪个动态创建的对象调用了函数?
【发布时间】:2015-06-05 10:38:06
【问题描述】:

我正在制作一个带有 Tkinter GUI 的 python 应用程序。到目前为止,它有一些动态创建的列表框,我会将它们全部链接到一个滚动条。我需要一种方法让yscroll() 知道哪个列表框已被滚动。将i 变量传递给yscroll() 不起作用。

from Tkinter import *

class MyApp(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.title(' - My App - ')

        self.listboxes = []
        for i in xrange(5):
            lb = Listbox(self, yscrollcommand=lambda i, *args: self.yscroll(i, *args))
            for x in xrange(30):
                lb.insert('end', x)

            lb.pack(fill='y', side='left')
            self.listboxes.append( lb )

        self.scrollbar = Scrollbar(self, orient='vertical')
        self.scrollbar.pack(side='right', fill='y')

    def yscroll(self, i, *args):
        print i
        print args

ma = MyApp()
ma.mainloop()

【问题讨论】:

  • TL;DR:试试yscrollcommand=lambda i=i, *args: ...
  • 您的建议 yscrollcommand=lambda i=i, *args: ... 无效,但 lb = eval( 'Listbox(self, yscrollcommand=lambda *args: ma.yscroll(%d, *args) )' % i ) 有效。有更清洁的解决方案吗?
  • 你看过例如effbot.org/tkinterbook/listbox.htm?这给出了一个使用一个滚动条滚动多个列表框的方法。
  • 是的,但这些列表框不是动态创建的
  • 我不明白为什么会有问题;只需在yview 中迭代self.listboxes

标签: python lambda tkinter


【解决方案1】:

usual recipe for using a variable from a loop in a lambda*args 一起使用时似乎无法正常工作。但是由于*args 在这种情况下似乎总是包含两个值(视口的开头和结尾,除非我弄错了),您可以像这样重写您的lambda

lb = Listbox(self, yscrollcommand = lambda x, y, i=i: self.yscroll(i, x, y))

或者您可以创建一种“元 lambda”,为 i 创建一个具有正确值的 lambda

make_callback = lambda i: lambda *args: self.yscroll(i, *args)
lb = Listbox(self, yscrollcommand = make_callback(i))

在定义lambda 时,两者都会在迭代中将i 绑定到i 的值。

【讨论】:

    猜你喜欢
    • 2021-08-17
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    相关资源
    最近更新 更多