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

Python 如何通过Tkinter按钮功能传递数据,lambda的问题,python,tkinter,lambda,tkinter-canvas,Python,Tkinter,Lambda,Tkinter Canvas,“起始页”有两个按钮:在新帧中拖动数据和打印数据。图(f,a)已定义,但未包含在以下代码部分中: button1 = ttk.Button(self, text="Show Graph", command=lambda: controller.show_frame(PageTwo)) button1.pack() button2 = ttk.Button(self, text="PL3",

“起始页”有两个按钮:在新帧中拖动数据和打印数据。图(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) 
按钮1然后在新的框架中显示该图

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正确执行。我可以在命令提示符中看到数据。弹出新的tkinter窗口,但不打印“动画”生成的任何数据

如果我从按钮2中删除LAMBDA,我会在新的帧中看到正确的绘图,但这不是我希望将来构建代码的方式。我不能删除lambda,因为最终会有30个按钮,就像按钮2一样

按钮2中的LAMBDA怎么了

按钮2中的LAMBDA怎么了

in
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,我会在新帧中看到正确的绘图

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) 
删除
lambda
关键字将在执行代码时立即执行
动画(3)
,以配置
按钮2
,而不是创建匿名函数。然后将
按钮2
的命令设置为
动画(3)
返回的任何内容。如果它不可调用,则实际上会忽略它

由于您没有为
animate
controller.show\u page
提供可用的代码,我们中的任何人都不可能确切地知道它是做什么的,但是从结果可以安全地假设
animate
图形
存储在属性/变量中,然后
controller.show\u page
(或未提供的
PageTwo
部分内容)从该属性/变量中检索
。这就是代码似乎仍在工作的原因:因为只有一个
要存储,
按钮1
将始终检索正确的图。如果您有多个按钮,则推测
按钮1
将始终显示上一个b的
无论按下哪个按钮,都会创建按钮,因为这是最近存储的

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

  • 在初始化
    PageOne
    之后或期间创建的内容与
    交互(和/或影响
    PageTwo
    的实例化)
  • 变量housing
    figure
    或另一个中间变量正在被垃圾收集,因为您没有维护对它的引用
由于我认为第一个更可能,我将特别挑选
a
f
作为候选变量:这两个变量都不是方法参数(而且它们似乎不是从
controller
中提取的,根据您的代码),因此它们是在更高范围内执行期间可以轻松更改的引用


如果您这样做,则更容易了解问题的具体原因。您还可能会发现,在编写MVCE时,问题就消失了,它将准确地告诉您出了什么问题,并允许您立即修复问题,而不是等待堆栈溢出的答案。

您的函数“animate”将j作为参数,但在任何一个函数中都不使用它声明。它在您的按钮lambda命令中调用。请提供