【问题标题】:call a function if the frame widget gets the focus in python(tkinter)如果框架小部件在 python(tkinter) 中获得焦点,则调用一个函数
【发布时间】:2022-01-10 04:30:09
【问题描述】:

working.py 中,我使用 focus() 获得焦点帧。
calculations.py 中,我正在尝试运行一些计算,这取决于所聚焦的帧。
我在main.py中的btn上打电话给calculations()

我想要实现的是,当我点击Calculate 按钮时,
如果e1_frame 专注,我应该添加 2 个数字和
e2_frame 专注时,我应该得到这两个数字的乘积。

但我收到以下错误:
TypeError: <lambda>() missing 1 required positional argument: 'e'

main.py

​​>
from tkinter import *
from working import create_frames
from calculations import calculations


class MyApp:
    def __init__(self, root):
        self.root = root

        self.var_e1 = StringVar(None)
        self.var_e2 = StringVar(None)
        self.var_lbl = StringVar(None)
        self.var_status_lbl = StringVar(None)

        create_frames(self)

        e1 = Entry(self.e1_frame, textvariable=self.var_e1)
        e2 = Entry(self.e2_frame, textvariable=self.var_e2)
        e1.focus_set()

        e1.pack()
        e2.pack()

        btn = Button(self.btn_frame, text='Calculate', command=lambda e: calculations(self, e))
        btn.pack()

        lbl = Label(self.root, font=20, textvariable=self.var_lbl)
        self.var_lbl.set('0')
        lbl.pack()

        status_lbl = Label(self.root, textvariable=self.var_status_lbl)
        status_lbl.pack(side=BOTTOM)
        self.var_status_lbl.set('Nothing is selected.')

def main():
    root = Tk()
    root.geometry('400x400')
    MyApp(root)
    root.mainloop()


if __name__ == '__main__':
    main()

工作.py

​​>
from tkinter import *

def focus(self, event):
    if event.widget == self.e1_frame:
        self.var_status_lbl.set(f'First value: {self.var_e1.get()}')
    if event.widget == self.e2_frame:
        self.var_status_lbl.set(f'Second value: {self.var_e2.get()}')
    
def create_frames(self):
    e0_frame = Frame(self.root)
    self.e1_frame = Frame(e0_frame)
    self.e2_frame = Frame(e0_frame)
    
    e0_frame.pack()
    self.e1_frame.pack(side=LEFT)
    self.e2_frame.pack(side=LEFT)

    self.btn_frame = Frame(self.root)
    self.btn_frame.pack(pady=10)

    self.e1_frame.bind('<Enter>', lambda e: focus(self, e))
    self.e2_frame.bind('<Enter>', lambda e: focus(self, e))

计算.py

​​>
from tkinter import *

def calculations(self, event):
    value1 = int(self.var_e1.get())
    value2 = int(self.var_e2.get())

    if event.widget == self.e1_frame:
        result = value1 + value2
    if event.widget == self.e2_frame:
        result = value1 * value2

    result = value1 + value2
    self.var_lbl.set(result)

【问题讨论】:

  • 按钮不向回调发送事件对象。
  • @Bryan Oakley,好的。那怎么才能得到我想要的结果呢?

标签: python-3.x tkinter focus frame


【解决方案1】:

这行对我来说似乎有问题:

lambda e: calculations(self, e)

当您为按钮命令定义lambda 时,您设置了参数e,它通常代表事件,它指的是由tkinter 生成并作为参数传递给有界函数/方法。

足够的上下文,让我们看看我们如何修复您的代码。我建议将calculation 设为普通方法,并将该事件对象留给更需要的情况。您可以通过调用focus_get() 来简单地获取哪个条目具有keyboard focus,它可以轻松替换您的event.widget if 语句。

import tkinter as tk

def cmd():
    print(root.focus_get())

root = tk.Tk()
e1 = tk.Entry()
e2 = tk.Entry()
b1 = tk.Button(command=cmd)

e1.pack()
e2.pack()
b1.pack()

【讨论】:

  • 我想过用这个方法。但是我应该如何在calculation.py中的if语句中使用这种方法
  • @MilindKhobragade event.widget 会像focus_get 一样返回一个小部件引用。我没有看到这里的问题。
  • focus_get() 可以很好地处理条目,但不能用于框架。在我的原始代码中,该框架中有几个小部件(框架、条目、标签、组合框)。我有很多这样的框架。我不想每次计算时都从特定框架中选择特定条目。
  • @MilindKhobragade 那么你的问题不清楚,你应该在你的问题中指出这一点。
  • @Thingamabobs,很抱歉,但我确实在我的问题中提到了聚焦框架小部件
猜你喜欢
  • 2021-04-04
  • 1970-01-01
  • 2018-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 2010-11-26
相关资源
最近更新 更多