在`tkinter`中,每次按下按钮时如何为标签获取不同的值?

3
我正在制作一个随机姓名生成器。我的GUI几乎已经完成了所有的内容。问题是,我只能按一次生成按钮来获取所需的所有值。我应该如何按下按钮无限次,每次按下按钮时都获取不同的值?
我需要做某种循环吗?我放置了一个lambda。这样可以防止值在您打开GUI后立即显示在屏幕上。这样,您可以按下按钮,并像正常情况下一样看到文本。
firstnameli = ['Chris ', 'Kevin ', 'Jeff ', 'Marty ', 'Dolen ']
lastnameli = ['Smith', 'Miller', 'Jones', 'Davis', 'Brown']

full_name = random.choice(firstnameli) + random.choice(lastnameli)

#this allows text to be put in the text box
estr = StringVar()
estr.set(full_name)

fullnameentry = Entry(MyWin, borderwidth=5, font=("Helvetica", 15))

def buttonfunc():
    fullnameentry.config(text=estr)

genbutton = Button(MyWin, text="GENERATE", activebackground="blue", command= lambda: buttonfunc())

@Jayjayyy 謝謝你讓我知道。我還有一個問題。你能不能解釋一下如何使用 .tk 把文本放在輸入框中?我導入 tkinter 的方法是從 tkinter 導入 * 。這和它有關嗎?(請原諒,我不知道如何使用代碼標籤。) - chrisT4
@Jayjayyy 我使用了 from tkinter import *,那么我导入 tkinter 的方式是否很重要呢?我知道 * 表示所有内容。因此,从 tkinter 包中导入所有内容是最合理的选择,不是吗? - chrisT4
@Jayjayyy 好的,谢谢你的帮助。 - chrisT4
1个回答

2

您只需生成一次随机名称。从那时起,estr 的值将始终相同。

如果您熟悉 lambda,则可以使用它将 full_name 转换为函数:

full_name = lambda: random.choice(firstnameli) + random.choice(lastnameli)

接下来,您需要调用full_name,因为它不再是一个简单的字符串变量,而是一个函数:

estr.set(full_name())

此外,您似乎忘记为fullnameentry设置textvariable=estr。整体来看:
firstnameli = ['Chris ', 'Kevin ', 'Jeff ', 'Marty ', 'Dolen ']
lastnameli = ['Smith', 'Miller', 'Jones', 'Davis', 'Brown']

full_name = lambda: random.choice(firstnameli) + random.choice(lastnameli)

#this allows text to be put in the text box
estr = StringVar()
estr.set(full_name())

fullnameentry = Entry(MyWin, textvariable=estr, borderwidth=5, font=("Helvetica", 15))

def buttonfunc():
    estr.set(full_name())

genbutton = Button(MyWin, text="GENERATE", activebackground="blue", command=buttonfunc)

我认为你的代码在某些地方可能有点太复杂了。这里提供一个极简的完整的 tkinter 示例,或许能对你有所帮助:
import tkinter as tk
import random

def random_name():
    first_names = ['Chris', 'Kevin', 'Jeff', 'Marty', 'Dolen']
    last_names = ['Smith', 'Miller', 'Jones', 'Davis', 'Brown']
    full_name = '{} {}'.format(random.choice(first_names), random.choice(last_names))
    return full_name

def update_label_and_entry():
    new_random_name = random_name()
    label.config(text=new_random_name)
    entry.delete(0, tk.END) # delete content from 0 to end
    entry.insert(0, new_random_name) # insert new_random_name at position 0

root = tk.Tk()
label = tk.Label(root)
label.pack()
entry = tk.Entry(root)
entry.pack()
button = tk.Button(root, text="New random name", command=update_label_and_entry)
button.pack()
root.mainloop()

当然,这段代码并不完美。例如,可以将first_nameslast_names移至全局命名空间中,以便其他方法也可以访问这些值。此外,您还可以为您的窗口或标签编写一个类,其中包括update_label方法。

我认为你应该将列表存储在全局命名空间中的函数外部。 - Mike - SMT
1
是的。我认为将这些列表放在函数外部是最好的,这样任何可能需要它们的代码都可以访问它们,以便在开发后期更新名称或其他随机生成器。从易用性的角度来看,我通常将这样的列表放在全局中。 - Mike - SMT
1
是的,我同意类是最好的解决方案,以避免全局命名空间的成为一个最大的优点。无论如何,感谢您将该信息添加到您的答案中。 - Mike - SMT
非常感谢大家。你们的代码更加有组织。但是它仍然无法工作。我仍然需要在按钮命令上使用lambda表达式,以便在打开GUI时不显示文本。我仍然无法无限次地按下按钮。只能按一次。 - chrisT4
@Jayjayy 是的,那正是我想要的。因此,才有了生成按钮。如果我不像第一个示例那样在按钮命令上放置 lambda 表达式,那么文本就会无动于衷。这个按钮根本没有任何功能。基本上什么也不会发生。 - chrisT4
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接