1

I am using SQLite and tkinter in Python 3.9 and got the following problem:

I got 1 SQLite DB with 2 tables.

I am using the column of one of the tables for a tkinter option menu. Now I want to trace the variable selected and display a corresponding value from the other table on a tk.label. OptionMenu and label are in the same window.

This is what I tried but returns: 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()))

If I let the function get the variable like this...

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))

it works, but I have 50 labels and dont want to copy + paste 50 functions. There hast to be a more elegant solution right, where I can give an argument to the callback function?! Please help. It seems like I have missunderstood something basic...

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Stogi
  • 13
  • 2

1 Answers1

1

Every function in python needs to return something. So when you do this callBackFct(optionMenuVar1.get()) callBackFct returns None since it returns nothing else. lambda is a way to store a function with provided arguments and is not executed when declared.

You can use an annonymous function for this case.

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()

Another maybe easier way to understand is to follow this Tutorial/Documentation here. Which could lead to the following code for you:

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))
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Thingamabobs
  • 7,274
  • 5
  • 21
  • 54
  • Thanks that works as intended. But why does it work contrary to my attempts? – Stogi Oct 10 '21 at 17:57
  • @Stogi every function in python needs to return something. So when you do this `callBackFct(optionMenuVar1.get())` callBackFct returns `None` since it returns nothing else. lambda is a way to store a function with provided arguments and is [not executed when declared](https://stackoverflow.com/a/5771787/13629335). – Thingamabobs Oct 10 '21 at 18:04