I'm trying to create a tkinter output window for a text based application

14,335

I think you might be making it more complicated than it needs to be.

For Tkinter at least it is very simple change console interactions into a GUI interaction instead.

The simplest example I can give is to use an Entry field for user input and a Text widget for the output.

Here is a simple example of a console based game being moved to a GUI using Tkinter.

Console number guessing game:

import random

print("simple game")
print("-----------")

random_num = random.randint(1, 5)
print(random_num)

x = True

while x == True:
    #Input for user guesses.
    guess = input("Guess a number between 1 and 5: ")

    if guess == str(random_num):
        #Print answer to console.
        print("You win!")
        x = False
    else:
        print("Try again!")

Here is the Tkinter GUI example of the same game:

import tkinter as tk
import random


root = tk.Tk()

entry_label = tk.Label(root, text = "Guess a number between 1 and 5: ")
entry_label.grid(row = 0, column = 0)

#Entry field for user guesses.
user_entry = tk.Entry(root)
user_entry.grid(row = 0, column = 1)

text_box = tk.Text(root, width = 25, height = 2)
text_box.grid(row = 1, column = 0, columnspan = 2)

text_box.insert("end-1c", "simple guessing game!")

random_num = random.randint(1, 5)

def guess_number(event = None):
    #Get the string of the user_entry widget
    guess = user_entry.get() 

    if guess == str(random_num):
        text_box.delete(1.0, "end-1c") # Clears the text box of data
        text_box.insert("end-1c", "You win!") # adds text to text box

    else:
        text_box.delete(1.0, "end-1c")
        text_box.insert("end-1c", "Try again!")

        user_entry.delete(0, "end")
# binds the enter widget to the guess_number function
# while the focus/cursor is on the user_entry widget
user_entry.bind("<Return>", guess_number) 

root.mainloop() 

As you can see there is a bit more code for the GUI but most of that is the GUI design.

The main part that you need to change is the use of entry vs input for your answers and the use of insert vs print for your response. The rest is really just design stuff.

If you want to keep the questions on a continuous nature you can update the label with a new question or you could even use tkinters askstring function for each new question. There are many options.

the main thing is getting the value of the user answer, using that answer to test with the question, then printing the results to the text box.

Share:
14,335
Luke
Author by

Luke

Updated on June 04, 2022

Comments

  • Luke
    Luke almost 2 years

    I have a script that continually takes in text and outputs text (its a text based game)

    I would like to run it through a tkinter GUI as opposed to the console

    Python : Converting CLI to GUI

    This question perfectly answers how to convert "print" into a GUI insert.

    The problem is that my game obviously runs through a ton of loops, and that screws up the "app.mainloop()" because it either never runs (and then the GUI never shows up) or you run it first, and it doesn't let anything else run.

    I suppose I could try and and stagger these loops somehow, but that seems very hackish. I could also try to modify my entire codebase to run inside the app.mainloop(), but what I really think I need is multiple threads. Problem is, I have no idea how to make that work.

    There are a few other questions, but they either don't work or don't make much sense: Tkinter with multiple threads

    Run process with realtime output to a Tkinter GUI

    Thanks.

    Edit: extremely simplified code:

    def moveNorth():
        print('You have moved north')
    
    def interpreter(command):
        if command == 'go north':
             moveNorth()
        else:
             print('invalid command')
    
    def listener():
         playerchoice = sys.stdin.readline().strip()
         return playerchoice
    
    if __name__ == '__main__':
        print('Welcome')
        while playing:
            interpreter(listener())
    
    • Nelson
      Nelson almost 7 years
      By while loops do you mean while bad_answer: ask_question()?
    • Luke
      Luke almost 7 years
      Yeah, the main one is my interpreter. Which basically constantly listens for player input and then does things based on that. Now that I think about it, that might be the only loop that causes problems as its the only infinite one. My code is pretty long though, so its possible I'm forgetting something.
    • Nelson
      Nelson almost 7 years
      Post some of your code, or at least a Minimal, Complete, and Verifiable example. Try to remove as much of your code as you can while keeping the bug intact
    • Luke
      Luke almost 7 years
      I don't really have any bugs, as I'm not sure how to start. But I've added an extremely (!) simplified version of my code.
  • Mike - SMT
    Mike - SMT almost 7 years
    @JaneDoe: You are welcome. You will find tkinter has many useful GUI widgets. For any text bases or images based game you can use Tkinter. If you ever feel like doing 2D or 3D games take a look at pygame.