1

I'm making a chat program, but I have run across a problem: the screen only updates after input. I'm using turtle to show the chat (I know, turtle isn't really that good for this purpose, but it's very simple.)

This is the code in my loop:

while True:    
    ind = userlist.index(user)
    if statlist[ind] == 'banned':
        print('You have been banned.')
        break
    word = input('>>> ')
    command(word)
    if word != '':
        chat = user + '(' + status + '): ' + word
        update_room(chat)
    refresh()

Pretty much everything can be ignored here, except the

word = input('>>> ')

and

refresh()

The refresh() is what updates the turtle room.

How could I make it so that it would print out new chat, even as the user is typing? Would 2 side-by-side while loops work?

I acknowledge that my program isn't that well organized and that to fix this I will probably have to rewrite this loop. Note: I'd rather not import anything, but if an import is needed then it would be great if that module came preloaded with python.

Or another question: Is it possible to have 2 infinite while loops running side by side at the same time?

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Kevin
  • 708
  • 2
  • 9
  • 20
  • 1
    You probably should look into using `tkinter` module as a GUI library for your application. See [Python chat client](http://stackoverflow.com/questions/15181731/python-formatted-chat-client) – mtadd May 13 '14 at 14:41
  • I know, but turtle seems to be working well enough. My only problem right now is that the input inside my loop is stopping the refresh(). – Kevin May 13 '14 at 15:54

2 Answers2

0

So I'm pretty new at python but I have an idea that will just be extremely repetitive. You need to first remove the input part and make a ton of functions like this:

def key_a:
    global key_in
    key_in = key_in + 'a'
def key_b:
    global key_in
    key_in = key_in + 'b'
def key_c:
    global key_in
    key_in = key_in + 'c'

Have it so if your input is enter, then it will set it to the word and reset the input variable.

def key_enter:
    global key_in
    global word
    word = key_in
    key_in = ''

Then bind your inputs (think of "win" as your window variable.)

win.listen()
win.onkeypress(key_a, 'a')

Also do the same for capital letters.

win.onkeypress(caps_key_a, 'A')

Please tell me if this helps.

TaCo
  • 13
  • 5
0

Here's an improvement on TaCo's answer suggesting onkeypress which enables real-time typed user input so you can re-render even if the user is holding down keys.

My contribution is to use a loop that calls a general function so there's no need to manually create a separate function per key. I've also provided a minimal, runnable example which should be easily adaptable to a chat interface, typing game or other context.

I haven't attempted to handle every key and edge case, so you might want to dig into the list of Tk keys and make sure it works for your needs. Feel free to suggest an improvement if you encounter any odd behavior.

import turtle
from datetime import datetime


def tick():
    current_time = datetime.now().strftime("%H:%M:%S")
    turtle.clear()
    turtle.goto(0, 50)
    turtle.write(current_time, align="center", font=font)
    turtle.goto(0, -50)
    turtle.write(f"'{text}'", align="center", font=font)
    turtle.update()
    turtle.Screen().ontimer(tick, 1000 // 30)


def handle_keypress(key):
    global text
    text += key


def handle_backspace():
    global text
    text = text[:-1]


def add_key_handler(key):
    turtle.Screen().onkeypress(lambda: handle_keypress(key), key)


font = "Courier New", 18, "normal"
text = ""
turtle.tracer(0)
turtle.penup()
turtle.hideturtle()

for i in range(33, 122):
    if i != 45:
        add_key_handler(chr(i))

turtle.Screen().onkeypress(handle_backspace, "BackSpace")
turtle.Screen().onkeypress(lambda: handle_keypress(" "), "space")
turtle.Screen().onkeypress(lambda: handle_keypress("-"), "minus")
turtle.listen()
tick()
turtle.exitonclick()

Reference: Is there a complete list of key event names used by turtle-graphics?

ggorlen
  • 44,755
  • 7
  • 76
  • 106