当我在 tkinter 程序中按提交时字典值不打印

dictionary value not printing when I press submit in tkinter program

我正在尝试创建以下 tkinter 程序:

  1. Select 4 个选项菜单中的每一个选项。
  2. 点击提交
  3. 来自字典的值,我在其中设置了键以匹配打印在“提交”旁边的选项组合。

例如用户从选项中选择“18-29,干燥,痤疮,是”。 我在单独的 python 文件中有一本字典,有 200 对。其中一对是: '18-29,干燥,粉刺,是':'Cetaphil'

打印出来的值应该是Cetaphil。但是,没有任何打印。我做错了什么?

import tkinter as tk
from rp import recommendedproducts

age_menu = [ 
    "18-29", 
    "30-49", 
    "50-81",
    ]

skintype_menu = [
    "dry", 
    "combination", 
    "normal", 
    "oily", 
    "sensitive"
    ]

mainskinconcern_menu = [
    "acne", 
    "anti-ageing", 
    "dehydration", 
    "pigmentation", 
    "sensitivity/redness"
    ]

cleanbeauty_menu = [
    "Yes",
    "No"
    ]


# root window
root = tk.Tk()
root.geometry("600x580")
root.title("SAVE MY SKIN")
root.configure(bg = "#32402f")

root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)


greeting = tk.Label(root, text = "Hello!", fg = "#faf2e9", bg = "#32402f",
                    font = ("Courier",20,"bold"), 
                    anchor = "w", 
                    padx = 30, 
                    pady = 10)

greeting.grid(row = 0, column = 0, sticky = tk.W)


instructions = tk.Label(root, text = "Fill in your details to get a list of "
                                     "product recommendations perfect for your specific " 
                                     "skincare needs!",
                        fg = "#faf2e9", 
                        bg = "#32402f", 
                        wraplength = 400, 
                        justify = "left", 
                        font = ("Courier",20),
                         anchor = "w", 
                        width = 60, 
                        padx = 30, 
                        pady = 10)

instructions.grid(row = 1, column = 0, sticky = tk.W)


disclaimer = tk.Label(root,text = "This is not intended as a subsititute "
                                  "for professional medical advice and should not be " 
                                  "relied on as health or personal advice. Always seek " 
                                  "the guidance of your doctor or other qualified health "
                                  "professional with any questions you may have "
                                  "regarding your health or a medical condition.", 
                      fg = "#faf2e9", 
                      bg = "#32402f", 
                      wraplength = 500, 
                      justify = "left",
                      font = ("Helvetica Neue",10), 
                      anchor = "w", 
                      width = 100, 
                      padx = 30, 
                      pady = 20)

disclaimer.grid(row = 10, column = 0, sticky = tk.W)

ageclicked = tk.StringVar()
ageclicked.set("age")
agedropdown = tk.OptionMenu(root,ageclicked,*age_menu)
agedropdown.config(fg = "#faf2e9", 
                   bg = "#32402f", 
                   font = ("helvetica neue",20), 
                   anchor = "e", 
                   width = 27)
agedropdown.grid(row = 2, column = 0, padx = 25, pady = 10, sticky = tk.W)

stclicked = tk.StringVar()
stclicked.set("skin type")
stdropdown = tk.OptionMenu(root,stclicked,*skintype_menu)
stdropdown.config(fg = "#faf2e9", 
                 bg = "#32402f", 
                 font = ("helvetica neue",20), 
                 anchor = "e", 
                 width = 27)
stdropdown.grid(row = 4, column = 0, padx = 25, pady = 10, sticky = tk.W)

mscclicked = tk.StringVar()
mscclicked.set("main skin concern")
mscdropdown = tk.OptionMenu(root,mscclicked,*mainskinconcern_menu)
mscdropdown.config(fg = "#faf2e9", 
                  bg = "#32402f", 
                  font = ("helvetica neue",20), 
                  anchor = "e", 
                  width = 27)
mscdropdown.grid(row = 6, column = 0, padx = 25, pady = 10, sticky = tk.W)

cbclicked = tk.StringVar()
cbclicked.set("clean beauty")
cbdropdown = tk.OptionMenu(root,cbclicked,*cleanbeauty_menu)
cbdropdown.config(fg = "#faf2e9", 
                  bg = "#32402f", 
                  font = ("Helvetica Neue",20), 
                  anchor = "e", 
                  width = 27)
cbdropdown.grid(row = 7, column = 0, padx = 25, pady = 10, sticky = tk.W)

def helptext():
    print("Contact judy.tran@live.com.au for more information.")

def userresult():
    userage = ageclicked.get()
    userst = stclicked.get()
    usermsc = mscclicked.get()
    usercb = cbclicked.get()
    print(userage,",", userst,",",usermsc,",",usercb)

def userrp():
    if userresult in recommendedproducts:
        print(recommendedproducts[userresult])

def show():
    result = tk.Label(root, text = userrp()).grid(row = 8, column = 1, sticky = tk.W)

helpButton = tk.Button( 
    text = "HELP", 
    width = 27,   
    highlightbackground = "#32402f",
    fg = "#faf2e9",
    font = ("avenir next condensed", 20, "bold"),
    command = helptext
    )
helpButton.grid(row = 9, column = 0, padx = 25, pady = 10, sticky = tk.W)

submitButton = tk.Button( 
    text = "SUBMIT", 
    width = 27,   
    highlightbackground = "#32402f",
    fg = "#faf2e9",
    font = ("avenir next condensed", 20, "bold"),
    command = show
    )
submitButton.grid(row = 8, column = 0, padx = 25, pady = 10, sticky = tk.W)


root.mainloop()

词典

recommendedproducts = {
    '18-29, dry, acne, Yes': 'Cetaphil',
    '18-29, dry, acne, No': 'Cetaphil',
    '18-29, dry, anti-ageing, Yes': 'Cetaphil',
    '18-29, dry, anti-ageing, No': 'Cetaphil',
    '18-29, dry, dehydration, Yes': 'Cetaphil',
    '18-29, dry, dehydration, No': 'Cetaphil',
    '18-29, dry, pigmentation, Yes': 'Cetaphil',
    '18-29, dry, pigmentation, No': 'Cetaphil',
    '18-29, dry, sensitivity/redness, Yes': 'Cetaphil',
    '18-29, dry, sensitivity/redness, No': 'Cetaphil',
    '18-29, combination, acne, Yes': 'Cetaphil',
    '18-29, combination, acne, No': 'Cetaphil',
    '18-29, combination, anti-ageing, Yes': 'Cetaphil',
    '18-29, combination, anti-ageing, No': 'Cetaphil',
    '18-29, combination, dehydration, Yes': 'Cetaphil',
    '18-29, combination, dehydration, No': 'Cetaphil',
    '18-29, combination, pigmentation, Yes': 'Cetaphil',
    '18-29, combination, pigmentation, No': 'Cetaphil',
    '18-29, combination, sensitivity/redness, Yes': 'Cetaphil',
    '18-29, combination, sensitivity/redness, No': 'Cetaphil',
    '18-29, normal, acne, Yes': 'Cetaphil',
    '18-29, normal, acne, No': 'Cetaphil',
    '18-29, normal, anti-ageing, Yes': 'Cetaphil',
    '18-29, normal, anti-ageing, No': 'Cetaphil',
    '18-29, normal, dehydration, Yes': 'Cetaphil',
    '18-29, normal, dehydration, No': 'Cetaphil',
    '18-29, normal, pigmentation, Yes': 'Cetaphil',
    '18-29, normal, pigmentation, No': 'Cetaphil',
    '18-29, normal, sensitivity/redness, Yes': 'Cetaphil',
    '18-29, normal, sensitivity/redness, No': 'Cetaphil',
    '18-29, oily, acne, Yes': 'Cetaphil',
    '18-29, oily, acne, No': 'Cetaphil',
    '18-29, oily, anti-ageing, Yes': 'Cetaphil',
    '18-29, oily, anti-ageing, No': 'Cetaphil',
    '18-29, oily, dehydration, Yes': 'Cetaphil',
    '18-29, oily, dehydration, No': 'Cetaphil',
    '18-29, oily, pigmentation, Yes': 'Cetaphil',
    '18-29, oily, pigmentation, No': 'Cetaphil',
    '18-29, oily, sensitivity/redness, Yes': 'Cetaphil',
    '18-29, oily, sensitivity/redness, No': 'Cetaphil',
    '18-29, sensitive, acne, Yes': 'Cetaphil',
    '18-29, sensitive, acne, No': 'Cetaphil',
    '18-29, sensitive, anti-ageing, Yes': 'Cetaphil',
    '18-29, sensitive, anti-ageing, No': 'Cetaphil',
    '18-29, sensitive, dehydration, Yes': 'Cetaphil',
    '18-29, sensitive, dehydration, No': 'Cetaphil',
    '18-29, sensitive, pigmentation, Yes': 'Cetaphil',
    '18-29, sensitive, pigmentation, No': 'Cetaphil',
    '18-29, sensitive, sensitivity/redness, Yes': 'Cetaphil',
    '18-29, sensitive, sensitivity/redness, No': 'Cetaphil',
    '30-49, dry, acne, Yes': 'Cetaphil',
    '30-49, dry, acne, No': 'Cetaphil',
    '30-49, dry, anti-ageing, Yes': 'Cetaphil',
    '30-49, dry, anti-ageing, No': 'Cetaphil', '30-49, dry, dehydration, Yes': 'Cetaphil', '30-49, dry, dehydration, No': 'Cetaphil', '30-49, dry, pigmentation, Yes': 'Cetaphil', '30-49, dry, pigmentation, No': 'Cetaphil', '30-49, dry, sensitivity/redness, Yes': 'Cetaphil', '30-49, dry, sensitivity/redness, No': 'Cetaphil', '30-49, combination, acne, Yes': 'Cetaphil', '30-49, combination, acne, No': 'Cetaphil', '30-49, combination, anti-ageing, Yes': 'Cetaphil', '30-49, combination, anti-ageing, No': 'Cetaphil', '30-49, combination, dehydration, Yes': 'Cetaphil', '30-49, combination, dehydration, No': 'Cetaphil', '30-49, combination, pigmentation, Yes': 'Cetaphil', '30-49, combination, pigmentation, No': 'Cetaphil', '30-49, combination, sensitivity/redness, Yes': 'Cetaphil', '30-49, combination, sensitivity/redness, No': 'Cetaphil', '30-49, normal, acne, Yes': 'Cetaphil', '30-49, normal, acne, No': 'Cetaphil', '30-49, normal, anti-ageing, Yes': 'Cetaphil', '30-49, normal, anti-ageing, No': 'Cetaphil', '30-49, normal, dehydration, Yes': 'Cetaphil', '30-49, normal, dehydration, No': 'Cetaphil', '30-49, normal, pigmentation, Yes': 'Cetaphil', '30-49, normal, pigmentation, No': 'Cetaphil', '30-49, normal, sensitivity/redness, Yes': 'Cetaphil', '30-49, normal, sensitivity/redness, No': 'Cetaphil', '30-49, oily, acne, Yes': 'Cetaphil', '30-49, oily, acne, No': 'Cetaphil', '30-49, oily, anti-ageing, Yes': 'Cetaphil', '30-49, oily, anti-ageing, No': 'Cetaphil', '30-49, oily, dehydration, Yes': 'Cetaphil', '30-49, oily, dehydration, No': 'Cetaphil', '30-49, oily, pigmentation, Yes': 'Cetaphil', '30-49, oily, pigmentation, No': 'Cetaphil', '30-49, oily, sensitivity/redness, Yes': 'Cetaphil', '30-49, oily, sensitivity/redness, No': 'Cetaphil', '30-49, sensitive, acne, Yes': 'Cetaphil', '30-49, sensitive, acne, No': 'Cetaphil', '30-49, sensitive, anti-ageing, Yes': 'Cetaphil', '30-49, sensitive, anti-ageing, No': 'Cetaphil', '30-49, sensitive, dehydration, Yes': 'Cetaphil', '30-49, sensitive, dehydration, No': 'Cetaphil', '30-49, sensitive, pigmentation, Yes': 'Cetaphil', '30-49, sensitive, pigmentation, No': 'Cetaphil', '30-49, sensitive, sensitivity/redness, Yes': 'Cetaphil', '30-49, sensitive, sensitivity/redness, No': 'Cetaphil', '50-81, dry, acne, Yes': 'Cetaphil', '50-81, dry, acne, No': 'Cetaphil', '50-81, dry, anti-ageing, Yes': 'Cetaphil', '50-81, dry, anti-ageing, No': 'Cetaphil', '50-81, dry, dehydration, Yes': 'Cetaphil', '50-81, dry, dehydration, No': 'Cetaphil', '50-81, dry, pigmentation, Yes': 'Cetaphil', '50-81, dry, pigmentation, No': 'Cetaphil', '50-81, dry, sensitivity/redness, Yes': 'Cetaphil', '50-81, dry, sensitivity/redness, No': 'Cetaphil', '50-81, combination, acne, Yes': 'Cetaphil', '50-81, combination, acne, No': 'Cetaphil', '50-81, combination, anti-ageing, Yes': 'Cetaphil', '50-81, combination, anti-ageing, No': 'Cetaphil', '50-81, combination, dehydration, Yes': 'Cetaphil', '50-81, combination, dehydration, No': 'Cetaphil', '50-81, combination, pigmentation, Yes': 'Cetaphil', '50-81, combination, pigmentation, No': 'Cetaphil', '50-81, combination, sensitivity/redness, Yes': 'Cetaphil', '50-81, combination, sensitivity/redness, No': 'Cetaphil', '50-81, normal, acne, Yes': 'Cetaphil', '50-81, normal, acne, No': 'Cetaphil', '50-81, normal, anti-ageing, Yes': 'Cetaphil', '50-81, normal, anti-ageing, No': 'Cetaphil', '50-81, normal, dehydration, Yes': 'Cetaphil', '50-81, normal, dehydration, No': 'Cetaphil', '50-81, normal, pigmentation, Yes': 'Cetaphil', '50-81, normal, pigmentation, No': 'Cetaphil', '50-81, normal, sensitivity/redness, Yes': 'Cetaphil', '50-81, normal, sensitivity/redness, No': 'Cetaphil', '50-81, oily, acne, Yes': 'Cetaphil', '50-81, oily, acne, No': 'Cetaphil', '50-81, oily, anti-ageing, Yes': 'Cetaphil', '50-81, oily, anti-ageing, No': 'Cetaphil', '50-81, oily, dehydration, Yes': 'Cetaphil', '50-81, oily, dehydration, No': 'Cetaphil', '50-81, oily, pigmentation, Yes': 'Cetaphil', '50-81, oily, pigmentation, No': 'Cetaphil', '50-81, oily, sensitivity/redness, Yes': 'Cetaphil', '50-81, oily, sensitivity/redness, No': 'Cetaphil', '50-81, sensitive, acne, Yes': 'Cetaphil', '50-81, sensitive, acne, No': 'Cetaphil', '50-81, sensitive, anti-ageing, Yes': 'Cetaphil', '50-81, sensitive, anti-ageing, No': 'Cetaphil', '50-81, sensitive, dehydration, Yes': 'Cetaphil', '50-81, sensitive, dehydration, No': 'Cetaphil', '50-81, sensitive, pigmentation, Yes': 'Cetaphil', '50-81, sensitive, pigmentation, No': 'Cetaphil', '50-81, sensitive, sensitivity/redness, Yes': 'Cetaphil', '50-81, sensitive, sensitivity/redness, No': 'Cetaphil'
  }

编辑函数 userrp() 为:

def userrp():
    userresult()
    print(recommendedproducts[userresult])

导致错误:

18-29, dry, acne, Yes
Exception in Tkinter callback
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/__init__.py", line 1892, in __call__
    return self.func(*args)
  File "/Users/xx/checki.py", line 153, in show
    result = tk.Label(root, text = userrp(), bg = '#32402f', fg = '#faf2e9').grid(row = 8, column = 1, sticky = tk.E)
  File "/Users/xx/checki.py", line 149, in userrp
    print(recommendedproducts[userresult])
KeyError: <function userresult at 0x7ff01fd3c9d0>

您忘记为 userresult() 执行函数调用。

if userresult in recommendedproducts 此处您正在检查函数对象是否是字典 recommendedproducts 中的键。所以发生的事情可以与此进行比较:

def foo(): pass

dict1 = {"a": 1, foo: 2}
dict2 = {"a": 1, "b": foo}

print(foo in dict1) # True
print(foo in dict2) # False

编辑:

再次查看代码后,发生了几件事情,这些事情看起来非常明显,即预期代码与正在执行的代码不同。

让我们从结构开始,然后向外工作。

目前这是嵌套函数调用的流程: show() -> userrp() -> userresult()

def userresult():
    userage = ageclicked.get()
    userst = stclicked.get()
    usermsc = mscclicked.get()
    usercb = cbclicked.get()
    print(userage,",", userst,",",usermsc,",",usercb)

userresult() 不会 return 任何东西,默认情况下此函数将 return None

if userresult() 将与 if None 换句话说,这个 if 条件永远不会 return True 与当前代码。

所以让我们修复那个:

def userresult():
    userage = ageclicked.get()
    userst = stclicked.get()
    usermsc = mscclicked.get()
    usercb = cbclicked.get()
# We must return this string, so it will be used whenever the function is called.
    return f"{userage}, {userst}, {usermsc}, {usercb}" 

现在我们可以将 return 值用于我们的 if 条件:

def userrp():
    if userresult() in recommendedproducts:
# We want this function to return as well.
        return recommendedproducts[userresult()] 

此功能现在应该可以正常工作,或者按预期工作。

def show():
    result = tk.Label(root, text = userrp()).grid(row = 8, column = 1, sticky = tk.W)

我制作了一个代码片段,希望阐明嵌套函数、print(built-in 函数) 和 return 语句的工作原理。

def foo():
    print("foo")
    # This function does not return anything and will return a NoneType object
    
def bar(): 
    return "bar"

foo() # Prints foo.
bar() # Prints nothing.
print(foo()) # Prints foo, then prints None
print(bar()) # Prints bar

x = foo() # x = None, and prints foo
y = bar() # y = "bar"
print(x) # Prints None
print(y) # Prints bar