【问题标题】:How to get a specific button to insert a value to a specific entry box in a series of buttons and entry boxes made by a for loop?如何获取特定按钮以将值插入由for循环制作的一系列按钮和输入框中的特定输入框?
【发布时间】:2021-12-15 00:46:24
【问题描述】:

我正在开发一个 Tkinter 项目,它基本上类似于游戏“MadTakes”的应用程序

它是如何工作的:

要求玩家“输入名词”或代词或任何类型的单词。一旦他输入了所有的单词,那个人就可以按“开始!”名词或形容词等有空格的故事将由玩家输入的单词填充。故事将因此完成,并将通过标签框显示。

程序的工作方式是,

我基本上是这样设计的,即问题的数量将决定通过 for 循环添加多少行问题和输入框。起初我在获取用户在每个条目框中输入的单个条目时遇到问题,但我能够解决这个问题,如下面的代码所示。

要查看我正在尝试实现的程序的工作示例,MadTakes 是我的项目所基于的。该网站有一个我想要获得的随机函数的工作示例。希望能帮助到你!我的代码如下。

这个帖子的原因是,

我在问题输入框旁边做了一个按钮,我希望将一个随机名词、形容词等插入到它旁边的输入框中。

不幸的是,这并没有发生。我能做的最好的就是让随机名词 (entry.insert) 出现在 for 循环生成的最后一个输入框中。

NounList = ["Apple", "Penguin", "Star", "Magnet", "Computer", "Anime"]
    def display(): #for displaying inside of a frame
        entries1 = []
        answer1 = []
        def execute():
            for txt in entries1:
            answer1.append(txt.get())             #gets what the user has inputted to each of the entry boxes and appends it to a list
        
    try:
        #the questions to ask on the left of the Entry boxes:
        TypeList=["Enter a noun ", "Enter a noun ", "Enter a verb ", "Enter a place ","Enter the place as before"] 
        for count, i in enumerate(TypeList):
            label = Label(frame, text=i+' ')
            label.grid(row=count, column=0)       #Each question is in a label on a different row
                    
            entry = Entry(frame, width=15, borderwidth=0)
            entries1.append(entry)                #The values that the user enters is appended to the list entries1
            entry.grid(row=count, column=1)       #Entry box placed next to the label
                
            def randnoun():                       #Random function to get a random noun from the list
                global NounList
                x = random.randint(0, (len(NounList)-1))
                random_noun = NounList[x]
                entry.delete(0, END) 
                entry.insert(0,random_noun)       #Theoretically this should enter the random noun to the entry box next to the random button
 
            if "noun" in i.lower():
                btn = Button(frame, width=8, text='RANDOM', command= randnoun)
                btn.grid(row=count, column=2)  #Random button placed on the right of Entry box

           #This button will start the "process" of taking the values of the entry boxes and eventually putting it in answer 1
           btn = Button(frame, width=14, text='GO!'command=execute) 
           btn.grid(row=count+1, column=1, pady=2)
            

例如,

输入一个名词:‏‏‎ ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎‎ ‎‏‎‎ ‎‏‎ [随机]

输入一个动词: ‎‏‎ | ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎‎ ‎‏‎‎ ‎‏‎ [随机]

输入形容词:‏‎ ‎‏‎ ‎|‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎ [随机]

当我按下 [RANDOM] 按钮时,这应该是输出:

输入一个名词:‏‏‎苹果公司[随机]

输入一个动词: ‎‏‎ | ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎‎ ‎‏‎‎ ‎‏‎ [随机]

输入形容词:‏‎ ‎‏‎ ‎|‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎ [随机]

并且answer1 必须包含“Apple”作为用户的第一个条目。 (我的意思是它应该在列表中以正确的顺序排列。它不应该与用户自己输入所有条目框时列表的外观不同)。 answer1 是我存储用户给出的所有值然后将其放入故事中的位置。

我目前的代码实现的是这样的:

输入一个名词:‏‏‎ ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎‎ ‎‏‎‎ ‎‏‎ [随机]

输入一个动词: ‎‏‎ | ‎‏‎ ‎‏‎ ‎‏‎ ‎‏‎‎ ‎‏‎‎ ‎‏‎ [随机]

输入形容词:‏‎ ‎‏‎ ‎|‏‎‏‎ ‎‏‎ ‎‏‎‎ Apple‎‏‎ ‎‏‎ ‎‎‎‎‎‎‎‎‎| [随机]

因为根据我的理解,entries1.append(entry) 获取相应条目框的值,但尝试在代码块中的任何其他位置 entry.insert 将导致它被插入到最后一个条目框。有什么解决办法吗?

我计划为所有问题创建这样的随机函数,以便有更多 if "verb" in i.lower()" 类型的语句和更多 randverbrandadj 等函数。他们都需要解决这个问题才能工作。

注意:此代码块位于主窗口中的框架内。我已经编辑了这段代码的某些部分,以便更容易地表达我的问题。为了提供更多信息,我可以提供项目整个代码的链接。

【问题讨论】:

  • 使用def randnoun(entry=entry): 使特定条目成为默认参数,并且global NounList 不是必需的,您可以删除该行

标签: python-3.x for-loop tkinter tkinter-entry tkinter-button


【解决方案1】:

您的主要问题是尝试访问 for/loop 内的单个 Entry 对象并在名为 display 的函数内声明列表。 我已在代码中的关键点添加注释以强调更改。

import random
import tkinter as tk

master = tk.Tk()
frame = tk.Frame(master)
frame.grid()

NounList = ["Apple", "Penguin", "Star", "Magnet", "Computer", "Anime"]
# questions to ask on the left of the Entry boxes:
TypeList=["Enter a noun ", "Enter a noun ", "Enter a verb ",
          "Enter a place ","Enter the place as before"]

# removed display() and declare lists in namespace so they are accessible
entries, entries1, answer1 = [], [], []

# used by RANDOM buttons
def redirect(f, *arg):
    return lambda: f(*arg)

def execute():
    for txt in entries1:
        answer1.append(txt.get())

# passing 'entry' solves primary problem
def randnoun(entry):
    random_noun = NounList[random.randint(0, (len(NounList) - 1))]
    entry.delete(0, tk.END)
    entry.insert(0, random_noun)

for count, i in enumerate(TypeList):
    label = tk.Label(frame, text = i, padx = 4)
    label.grid(row = count, column = 0)

    entry = tk.Entry(frame, width = 15, borderwidth = 0)
    entries1.append(entry)
    entry.grid(row = count, column = 1)

    if "noun" in i.lower():
        btn = tk.Button(
            frame, width = 8, text = "RANDOM",
            # redirect is necessary for passing entry to randnoun inside for loop
            command= redirect(randnoun, entry))
        btn.grid(row = count, column = 2)

    btn = tk.Button(frame, width = 14, text = "GO!", command = execute)
    btn.grid(row = count + 1, column = 1, pady = 2)
master.mainloop()

【讨论】:

  • redirect() 完成了这项工作!非常感谢!顺便说一句,display() 有一个我错过的缩进错误。我也理解了我的其他错误。
  • 好一个@Karan Hathwar,编码愉快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-22
  • 1970-01-01
  • 2021-06-08
  • 2014-02-25
  • 1970-01-01
  • 2011-09-26
相关资源
最近更新 更多