11

I'm trying to write a (command line) python program that will accept input from the user while still printing data above it. I am trying to make a chat program.

Example:

[stuff prints here]
hello
warning: the time is 27:64

Please enter your input: asdf

So I have typed the asdf, but while I am typing, the output above continues to update. If I want, I can continue to type while the output is being generated. Then if I press enter, something else happens. The input field should always stay below the the outputted text; if more text is displayed, the input field gets pushed down (but its contents remain in place).

My thoughts were:

  • This needs to be some sort of non-blocking read...
  • ...or maybe threading? One thread for input, one for output.
  • Might I need to do some cursor manipulation (i.e. moving the cursor upwards, printing output, returning cursor to user input area)?

I realize that a GUI would be much easier to do. I'll probably end up just doing this with tkinter. But I was nevertheless wondering if this sort of thing is possible in python on the command line.

Thanks.

EDIT: I forgot to mention that I do know how to erase text with carriage returns (\r). The problem really is making sure that when I erase the line, I don't clear the user input: So if a new line comes up while I am typing, I don't want the input I have so far to be erased.

baum
  • 959
  • 13
  • 27
  • possible duplicate of [In Python, how to change text after it's printed?](http://stackoverflow.com/questions/5426546/in-python-how-to-change-text-after-its-printed) – SimonT Jan 25 '14 at 21:57
  • 2
    Very quick and dirty part solution - loop printing output, when `KeyboardInterrupt` occurs prompt for input. That way you are only blocking occasionally, not constantly. Better solution (especially for linux) - use the `curses` module or some such. – rlms Jan 25 '14 at 21:59
  • @SimonT: forgot to mention that I have that part down with carriage returns; I'll edit to reflect that. – baum Jan 25 '14 at 22:01
  • @sweeneyrod interesting idea, not necessarily a bad thing to have an escape sequence to start typing... but then of course you can't see new output while typing. – baum Jan 25 '14 at 22:05
  • Interesting development (not a solution, but close): If I have an input thread and an continuous output thread, of the output thread will write over my input. BUT: if I press delete, somehow control-R is called (bash history control code), and my line reappears. this is a possibility, though I doubt this is cross-platform. – baum Jan 25 '14 at 22:31
  • ... So I should be able to use readline. If i get something working I'll post a solution. – baum Jan 25 '14 at 22:45

1 Answers1

1

The classic approach to such problem would be:

  • Have a server module listening to incoming requests, and printing the input
  • Have a threaded client module(forked in to 2 threads, in our example).
  • The clients will use be able to behave simultaneously, by using the threading library of Python.
py_script
  • 808
  • 2
  • 16
  • 38
  • 2
    But how do you print and accept user input? I'm not so much asking about the networking side of things (this I already have sorted out) but rather the CLI/logistics side of things. – baum Jan 25 '14 at 22:07
  • Not sure I understand the question, but I can give you an example based on what I have understood: When you run the application, ideally, there should be a server daemon, and two client windows. Clients are connecting to the server, probably through sockets. Client1 sends a message, server receives it, checks which should be the receipient and flushes it to the respective client's output text area. If you are writing at the same time, it is not a problem, as the server knows about the input only, when you hit the enter. – py_script Jan 25 '14 at 22:15
  • Right. But if I am typing _as a message is coming in_, I want that message to be displayed above my text-entry area. – baum Jan 25 '14 at 22:19
  • Server receives the message and it flushes it out to the output. You are still writing your message and server know nothing about that. Finally when you hit enter, your message appears below the previous one. Sorted with chronological order, if you like. – py_script Jan 25 '14 at 22:57
  • 1
    If you are happy with that answer please accept it by hitting the "check" sign on the left of it. Thanks – py_script Jan 25 '14 at 22:58
  • But then there is no continuous update while you are typing. What you specified is a possibility but is not the answer to my problem. – baum Jan 25 '14 at 23:06
  • So, you want to have the output updated every time you type, instead of hitting enter? It is pretty much the same logic, but instead, you will do that logic(client1->server->client2) every time you are changing the content of the input area – py_script Jan 25 '14 at 23:53