0

I am working on a Tkinter project that is basically like a app for the game "MadTakes"

How it works:

The player gets asked to "Enter a noun" or a pronoun or any type of word. Once he has entered all the words, that person can press "Go!" and a story which had blanks for the nouns or adjectives, etc., will be filled by the words that the player had inputted. The story would thus be completed and it will be displayed through a Label Box.

The way the program works is that,

I basically made it such that the number of questions would decide how many rows of questions and entry boxes would be added through a for loop. At first I had the problem getting the individual entries made by the user in Each Entry box, but I was able to solve that as shown in the code below.

To see a working example of the program I am trying to achieve, MadTakes is what my project is based on. That website has a working example of the random function I am trying to get. Hope it helps! My code is given below.

The reason for this post is,

I made a button next to the Entry boxes for the questions which I hoped would insert a random noun, adjective etc. into the Entry box right next to it.

Unfortunately, that did not happen. The best I could do was get the random noun to appear (entry.insert) into the last entry box that is produced by the for loop.

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)
            

For example,

Enter a Noun:‏‏‎ ‎‏‏‎ ‎‏‏ ‎‏‏‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏ ‎‏‏‎ ‎‏‏‎ ‎‏‏|‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‎‎‎‎‎‎‎‎| [RANDOM]

Enter a Verb: ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ |‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‎‎‎‎‎‎‎‎| [RANDOM]

Enter an Adjective:‏‏‎ ‎‏‏‎ ‎|‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‎‎‎‎‎‎‎‎| [RANDOM]

When I press [RANDOM] Button, this should be the output:

Enter a Noun:‏‏‎ ‎‏‏‎ ‎‏‏ ‎‏‏‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏ ‎‏‏‎ ‎‏‏‎ ‎‏‏|‏‏‎ ‎‏‏‎ ‎‏‏‎ Apple‎‏‏‎ ‎‏‏‎ ‎‏‏‎‏‏‎ ‎ ‎‏‏‎ ‎‎‎‎‎‎‎‎‎| [RANDOM]

Enter a Verb: ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ |‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‎‎‎‎‎‎‎‎| [RANDOM]

Enter an Adjective:‏‏‎ ‎‏‏‎ ‎|‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‎‎‎‎‎‎‎‎| [RANDOM]

And the the answer1 must contain "Apple" as the first entry by the user. (What I mean is it should be in the correct order in the list. It shouldn't differ from how the list would look like if the user himself entered into all the Entryboxes). answer1 is where I store all the values given by the user and then put it into the story.

What my current code achieves is this:

Enter a Noun:‏‏‎ ‎‏‏‎ ‎‏‏ ‎‏‏‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏ ‎‏‏‎ ‎‏‏‎ ‎‏‏|‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‎‎‎‎‎‎‎‎| [RANDOM]

Enter a Verb: ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ |‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‎‎‎‎‎‎‎‎| [RANDOM]

Enter an Adjective:‏‏‎ ‎‏‏‎ ‎|‏‏‎‏‏‎ ‎‏‏‎ ‎‏‏‎ Apple‎‏‏‎ ‎‏‏‎ ‎‏‏‎‏‏‎ ‎ ‎‏‏‎ ‎‎‎‎‎‎‎‎‎| [RANDOM]

Because according to my understanding, the entries1.append(entry) gets the values of the corresponding Entryboxes but trying to entry.insert it anywhere else in the code block will result in it getting inserted to the last entry box. Is there any work around to this?

I plan on making such random functions for all of the questions so there will be more if "verb" in i.lower()" type of statements and more randverb, randadj etc. functions. All of them need this problem solved to work.

Note: This code block is inside a frame which is placed in the main window. I have edited some parts of this code to make it easier to express my problem. To provide more info, I can give a link to the entire code of the project.

  • use `def randnoun(entry=entry):` to make the specific entry a default argument and also `global NounList` is not necessary, you can remove that line – Matiiss Oct 30 '21 at 19:12

1 Answers1

0

Your main problem was attempting to access individual Entry objects inside a for/loop and declaring lists inside a function called display. I've placed remarks at critical points in your code to emphasis the changes.

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()
Derek
  • 1,916
  • 2
  • 5
  • 15