Home > Software engineering >  How to pass input from one entry widget into multiple sequential functions OR how to pass button inp
How to pass input from one entry widget into multiple sequential functions OR how to pass button inp

Time:09-03

So I essentially have 2 codes at the moment, a text-based game and a GUI, that function separately that I'm trying to combine. The game basically has a series of functions it can call based on user input - eg:

def game():
    print("Would you like to play? [Y/N]")
    start = inpupt().lower().strip()
    if start == 'y':
        adventure()
    elif start == 'n':
        goodbye()

with adventure() calling two or more options leading to their respective functions, etc. etc.

The GUI is tkinter based, has a label, a scrolled text box, an entry widget, and an "enter" button. I've created my own "print" functions that allow the code to input text into the scrolled text box, and then disable the box again, so that the user doesn't directly edit it. I've also been able to have the button/enter key pull text from the entry widget and print it in the text box, and then clear the entry widget.

What I don't know how to do is get the entry widget/button to integrate with the different game functions. It seems like you can set a function for the button - which is how I was able to pull the entry text, but I don't know how to then pass that pulled information on to another function.

I tried something like this which worked for just entering text into the scrollbox with this attached to the button as the command:

def clicked(self, variable, event=None):
    self.variable = self.userin.get()
    self.print1(self.variable)
    self.clear_text()

But then I don't know how to call that as a part of my game function. This was all I could think of (and I know it's wrong and bad, ok?):

def game():
    print1("Would you like to go on an adventure? [Y/N]")
    clicked(self, start) #trying to use "start" as the variable 
    if self.start == "y":
        self.print1("Let's go!")
    elif self.start == "n":
        self.print1("Okay, bye!")
    else:
        self.print1("What?")

But then game() is trying to call the clicked() function instead of waiting for the button, so it's not really pulling the input from the user. I also kept getting the error that "start" was not defined, probably for that reason. (Also please ignore any errors in where "self" is supposed to go... this was my first stab at using classes, and I know I'm probably doing more wrong than right, I'd figure it out if you had a solution in this vein)

So is there a way to get the button to pass the user input into the function, without the function being exclusive to the button? (Like I know I could get it to make one choice, but then how would I get the button to function for the next choice?)

My "Plan B" was to just create buttons for user input - either yes/no or a/b/c/d - so that the function of the buttons would be the same : return "B" (or something like that), but then how would I get the function to pull that input? Or wait for that input?

I have googled this six ways to Sunday, and have not found anything that works for this situation. I thought I'd found something with the CallBack function - but then I realized they were using it for multiple buttons, instead of the same button for multiple functions.

CodePudding user response:

Here is a quick example using some of what you provided that should demonstrate how you can link your conditions for the button. Regardless of how you actually structure your code, the concept should demonstrate one way you could do it. I would look into some tkinter tutorials as these concepts are well documented. I hope this helps.

import tkinter as tk


def clicked():
    entry_value = entry.get()
    entry.delete("0", tk.END)
    print(entry_value)

    # set up whatever conditions you want the button to be linked with
    if str(entry_value) == "y":
        print("Alright, get ready!")
        # now you call your function to start the game here
        start_game()
    elif str(entry_value) == "n":
        print("Ok, maybe another time")
        label.config(text="Ok, maybe another time, closing the game now")
        root.after(2500, lambda: root.destroy())
    else:
        label.config(text="Invalid entry, please enter a lower case 'y' or 'n'")
        label.after(3000, reset_label)

                
def start_game():
    # just an example this creates a new window to simulate some bhavior of the game
    top = tk.Toplevel()
    top.geometry("500x500")
    top.title("New Game")
    top.config(bg="blue")
    # add things to the toplevel that shows the game? not sure what you want to do

def reset_label():
    label.config(text="Would you like to play? [y/n]")
    
root = tk.Tk()
root.geometry("300x200")

label = tk.Label(root, text="Would you like to play? [y/n]")
label.pack()

entry = tk.Entry(root)
entry.pack()

button = tk.Button(root, text="Go", command=clicked)
button.pack()


root.mainloop()

CodePudding user response:

Thank you for the suggestions! This is what I worked out (once I figured out the right way to change the command - no extra parenthesis!):

def choice1(event=None):
    whereto = userin.get().lower().strip()
    if whereto == "woods":
        print1("The woods are spooky")
        button["command"] = woods
    elif whereto == "tavern":
        print1("The tavern is crowded")
        button["command"] = tavern
    else:
        print1("What?")
        print1("Woods or Tavern?")

def clicked(event=None):
    start = userin.get().lower().strip()
    print1(userin.get())
    clear_text()
    changelabel("Let's go!")
    if start == "y":
        print1("Lets go!")
        print1("Woods or Tavern?")
        button["command"] = choice1
    elif start == "n":
        print1("Ok bye!")
    else:
        print1("What?")
        print1("Do you want to play a game?")

I'd like to make the return key work the same as the button click, so I suspect I'm going to have to add the root.bind('<Return>', func) everywhere too

  • Related