10

I have been trying to make my own UI that is text-based in python 2.7, but I thought of an idea about input. So I figured something like this: input = raw_input("|" + "input: ".center(78) + "|"), but of coarse, the cursor is way far on the right (just realized it wouldn't work before i even typed it in :P). So, the question is, is how do I put an input in the middle of the screen with text on the same line (on both sides) and have the cursor type after I write "Input: "? And if your wondering, im using this:

if True:
    print c + "Hi! This is a text-based GUI!".center(78, h) + c
    print c + "-" * 78 + c
    print v + "OPTIONS".center(78) + v
    print c + "-" * 78 + c
    print v + "1 - Quit".center(78) + v
    for i in range(1, 7):
        print v + " " * 78 + v
    print c + "-" * 78 + c

in the interpreter and it looks decent:

+------------------------Hi! This is a text-based GUI!-------------------------+
+------------------------------------------------------------------------------+
|                                   OPTIONS                                    |
+------------------------------------------------------------------------------+
|                                   1 - Quit                                   |
|                                                                              |
|                                                                              |
|                                                                              |
|                                                                              |
|                                                                              |
|                                                                              |
+------------------------------------------------------------------------------+

Note: I use Windows XP

Cold Diamondz
  • 523
  • 3
  • 6
  • 12

6 Answers6

19

What you need for this sort of text UI is a terminal library that understands the basic layout and capabilities of your screen and the supported input devices.

On Linux (or OSX), the widely recognised standard is ncurses. Python provides a module to wrap this native library. However, this (and any package that uses this - e.g. urwid) are of limited use on Windows.

In your case, you need to use something else that provides access to the native Win32 console API. That would either be cygwin, a custom install of PDcurses, or a package like pywin32.

Alternatively, if you really don't want to worry about all that OS specific nonsense, you could just install asciimatics. This provides a cross-platform API to place text anywhere on the screen and process keyboard input. In addition, it provides higher level widgets to create text UIs like this:

Text UI widgets

Full disclosure: Yes - I am the author of this package.

Peter Brittain
  • 13,489
  • 3
  • 41
  • 57
  • Although it reacts kind of slow to keyboard input (as far I have tested it), I have to say that this is pretty impressive. Thanks for sharing. – bgusach Nov 07 '16 at 09:47
  • 1
    Thanks. You might be seeing https://github.com/peterbrittain/asciimatics/issues/32 (which is basically that I have overloaded one of the demos). If not, please feel free to raise a new issue on github. – Peter Brittain Nov 07 '16 at 11:24
7

Also try useful built atop curses high level framework urwid. With that thing you could do rich and colorful interfaces. Buttons, edit fields, even status bars and progress bars and all that you need. To start working you only need Python curses installed and urwid folder with its sources (you can transfer whole urwid library with your application as standalone bundle!). It works even under cygwin under Windows XP/7 where is, as we know, no curses ports for Python.

urwid portfolio

No more lowlevel, sometimes very boring curses :)

ulidtko
  • 14,740
  • 10
  • 56
  • 88
rook
  • 5,880
  • 4
  • 39
  • 51
  • You can also easily modify (thank to `Python`) source widgets for project or educational needs. – rook Aug 12 '13 at 08:30
3

Adding another option few years after original question. As per the author of Picotui:

Picotui is a Text User Interface (TUI) widget library for Python3. It is known to work with CPython3 and Pycopy (Unix version is officially supported for the latter), but should work with any Python3 implementation which allows to access stdin/stdout file descriptors.

The author also goes on to compare PicoTUI against Urwid. Some interesting points there. I am hoping to use PicoTUI for a project I am looking to start. Admittedly, no first hand experience. Came across this question when looking for answers for my TUI (Text-based UI or Terminal-based UI, much in GUI sense) Python library, so thought of adding this option.

bdutta74
  • 2,798
  • 3
  • 31
  • 54
1

The input() function is not nearly sophisticated for this kind of task.

You'd be better of with a library that can control the Unix terminal, such as the curses library. The library essentially lets you build a simple terminal GUI.

If you need more, take a look at Urwid as well. Urwid offers more complex GUI widgets for the discerning terminal GUI developer.

You can't use the curses module on Windows unfortunately; apparently there are DOS and OS/2 ports but it is primarily a POSIX-only library. On Windows you'll have to use a port such as wcurses, or you could try the console module (the latter drives the Windows CMD console in a similar manner).

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1

For a good text-based ui, you could use curses.

http://docs.python.org/2/library/curses.html

seanmcl
  • 9,740
  • 3
  • 39
  • 45
  • That is indeed an option, alas too low level -- a'la nuts and bolts. My first professional project after college was a rather big Ncurses UI for a X.400 mailing system written in C some 22 years back. It requires very significant amount of plumbing and "widget" development (a term that I wasn't even aware of at that time), to make anything non-trivial with it. – bdutta74 Dec 06 '19 at 04:21
1

Well, all of your answers were great, but I think I can use this for inputs instead of a 3rd party library:

c = "+"
h = "-"
print c + h*78 + c
inputa = raw_input(" "*32 + "Input example: ")
print c + h*78 + c

which would work for me.

Cold Diamondz
  • 523
  • 3
  • 6
  • 12