繁体   English   中英

如何通过 Tkinter 按钮功能传递数据,lambda 问题

[英]How to pass data through a Tkinter button function, problems with lambda

起始页有两个按钮:拉数据和在新框架中绘制数据。 figure(f,a) 已定义,但未包含在以下代码部分中:

 button1 = ttk.Button(self, text="Show Graph",
                            command=lambda: controller.show_frame(PageTwo))
 button1.pack()

 button2 = ttk.Button(self, text="PL3",
                            command=lambda: animate(3)) 
 button2.pack()

Button2 启动函数“animate”,它接受一个参数(J),提取对应于 J 的数据,然后绘制散点图。

def animate(j)
   a.plot(Date, Left,"go", label = "price")
   title = "Left Fid"
   a.set_title(title) 

Button1 然后在新框架中显示图形

class PageTwo(tk.Frame):
def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)
    label = tk.Label(self, text="Graph page", font=LARGE_FONT)
    label.pack(pady=10,padx=10)


    button1 = ttk.Button(self, text="back to home",
                        command=lambda: controller.show_frame(StartPage))
    button1.pack()

    canvas = FigureCanvasTkAgg(f,self)
    canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand = True)

    canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand = True) 

问题:我想要绘制的数据正在由 animate.js 正确执行。 我可以在命令提示符中看到数据。 新的 tkinter 窗口弹出,但没有绘制从“animate”生成的任何数据。

如果我从按钮 2 中移除 LAMBDA,我会在新框架中看到正确的图,但这不是我想为未来构建代码的方式。 我无法删除 lambda,因为最终会有 30 个按钮,就像按钮 2 一样。

按钮 2 中的 LAMBDA 发生了什么?

按钮 2 中的 LAMBDA 发生了什么?

tkinter.Button命令参数需要对函数的引用。

lambda是创建匿名、简单函数的语法。 它的语法实际上与函数的签名相同。

def func(a, *args, b = 2, **kwargs):
    return a+b
func = lambda a, *args, b = 2, **kwargs: a+b

因为lambda是一种创建函数的简单方法,人们经常在tkinter使用它来捆绑具有特定于给定回调/命令的预定参数的函数。

Button2 启动函数“animate”,它接受一个参数(J),提取对应于 J 的数据,然后绘制散点图。 [...]

Button1 然后在新框架中显示图形 [...]

如果我从按钮 2 中移除 LAMBDA,我会在新框架中看到正确的图

删除lambda关键字会在执行代码以配置button2而不是创建匿名函数时立即执行animate(3) 然后将button2的命令设置为animate(3)返回的任何内容。 如果它不可调用,那么它会被有效地忽略。

因为您没有为animatecontroller.show_page提供可行的代码,所以我们中的任何人都无法确定它的作用,但从结果中可以安全地假设animatefigure存储在属性/变量中,并且然后controller.show_page (或未提供的PageTwo某些部分)从该属性/变量中检索figure 这就是代码似乎仍然有效的原因:因为只有一个figure要存储, button1将始终检索正确的数字。 如果您有多个按钮,则无论按下哪个按钮, button1可能始终显示创建的最后一个按钮的figure ,因为这是最近存储的figure

显然,这一切的中心问题可能是animate如何存储figure以及controller.show_page / PageTwo检索图形的方式。 两种广义的解释:

  • PageOne初始化之后或期间创建了一些与figure交互(和/或影响PageTwo的实例化)的东西。 使用lambda ,此对象在创建时具有特定值,该值在对象完成其进程(无论是初始化、调用后续方法、设置三级变量等)后才会更改。 如果没有lambda ,则立即调用animate ,这会更改此对象以反映figure的创建。
  • 变量房屋figure或另一个中间变量正在被垃圾收集,因为您没有维护对它的引用。

由于我认为第一个更有可能,我会特别挑选af作为候选:这些变量都不是方法参数(并且它们似乎不是从controller提取的,根据您的代码),因此它们是引用在更高的范围内执行期间可以轻松更改。

如果您将代码简化为 MVCE则更容易看出问题究竟是什么。 您还可能会发现在编写 MVCE 时问题消失了,它会准确地告诉您出了什么问题,并让您立即修复它,而不是等待 Stack Overflow 的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM