首页 > 解决方案 > 使用 tkinter 作为回调函数的参数

问题描述

我在 Python 3.9 中使用 SQLite 和 tkinter 并遇到以下问题:

我得到了 1 个带有 2 个表的 SQLite DB。

我正在使用其中一个表的列作为 tkinter 选项菜单。现在我想跟踪选定的变量并在tk.label. OptionMenu 和标签在同一个窗口中。

这是我尝试过但返回的方法: TypeError: 'NoneType' object is not callable

def callBackFct(var):
        cur.execute("""SELECT nameFromColumn FROM sqlDbTable WHERE condition = ?""", (var,))
        f = cur.fetchall()
        tkLabel1.config(text = f[0][0])

optionMenuVar1.trace("w", callBackFct(optionMenuVar1.get()))

如果我让函数像这样获取变量...

def callBackFct(*args):
        var = optionMenuVar1.get() # getting variable inside function
        cur.execute("""SELECT nameFromColumn FROM sqlDbTable WHERE condition = ?""", (var,))
        f = cur.fetchall()
        tkLabel1.config(text = f[0][0])

optionMenuVar1.trace("w", callBackFct))

它有效,但我有 50 个标签,不想复制 + 粘贴 50 个函数。必须有一个更优雅的解决方案吧,我可以在哪里给回调函数一个参数?!请帮忙。好像我误解了一些基本的东西......

标签: pythontkintercallback

解决方案


python 中的每个函数都需要返回一些东西。因此,当您执行此操作时, callBackFct(optionMenuVar1.get()) callBackFct 返回 None,因为它不返回任何其他内容。lambda 是一种使用提供的参数存储函数的方法,并且在声明时不执行

对于这种情况,您可以使用匿名函数。

import tkinter as tk
def test(x):
    print(x)
root = tk.Tk()
var = tk.StringVar()
opt = tk.OptionMenu(root,var,value='hi')
opt.pack()
var.trace('w',lambda *args:test(var.get()))

root.mainloop()

另一种可能更容易理解的方法是在此处遵循本教程/文档。这可能会为您带来以下代码:

def callBackFct(var,idx,mod):
        cur.execute("""SELECT nameFromColumn FROM sqlDbTable WHERE condition = ?""", (var.get(),))
        f = cur.fetchall()
        tkLabel1.config(text = f[0][0])

optionMenuVar1.trace("w", callBackFct))

推荐阅读