peterbrittain / asciimatics Goto Github PK
View Code? Open in Web Editor NEWA cross platform package to do curses-like operations, plus higher level APIs and widgets to create text UIs and ASCII art animations
License: Apache License 2.0
A cross platform package to do curses-like operations, plus higher level APIs and widgets to create text UIs and ASCII art animations
License: Apache License 2.0
The examples in forms.py
seems to be slow, e.g. typing in the input text was slightly bu perceavibly unresponsive
the more I dig into issue #2 the more obvious it becomes that there is no modern, cross platform, standard API for full console input and output in Python.
Why is there no standard Python API for all of this? Let's try to fix that with the Screen class.
So, this package looks of interest to non-Pythoneers, like myself. Unfortunately, pip install asciimatics
isn't enough information if you don't already know quite a bit about Python:
pip install asciimatics
doesn't really tell me where it installs it. How do I run it? Did it install a binary somewhere (if so, it's not in my $PATH
.) What does that binary run? Python files?samples/
directory?I read the quick start guide, which really wasn't; and then ended up reading most of https://packaging.python.org/en/latest/installing before I discovered that I'm supposed to setup a virtualenv
, and then pip3 install -r requirements.txt
(or so I think? I'm not even sure if that ended up being correct!)
Even having done all of that, I can't run the samples: from every one I've tried, I get errors like the following:
(asciimatics)> python samples/xmas.py
Traceback (most recent call last):
File "samples/xmas.py", line 65, in <module>
Screen.wrapper(demo)
File "/Users/ec/Documents/Code/Source/asciimatics/lib/python3.5/site-packages/asciimatics-1.5.0-py3.5.egg/asciimatics/screen.py", line 479, in wrapper
File "/usr/local/Cellar/python3/3.5.0/Frameworks/Python.framework/Versions/3.5/lib/python3.5/curses/__init__.py", line 94, in wrapper
return func(stdscr, *args, **kwds)
File "/Users/ec/Documents/Code/Source/asciimatics/lib/python3.5/site-packages/asciimatics-1.5.0-py3.5.egg/asciimatics/screen.py", line 477, in _wrapper
File "samples/xmas.py", line 61, in demo
screen.play([Scene(effects, -1)], stop_on_resize=True)
File "/Users/ec/Documents/Code/Source/asciimatics/lib/python3.5/site-packages/asciimatics-1.5.0-py3.5.egg/asciimatics/screen.py", line 672, in play
File "/Users/ec/Documents/Code/Source/asciimatics/lib/python3.5/site-packages/asciimatics-1.5.0-py3.5.egg/asciimatics/screen.py", line 879, in clear
File "/Users/ec/Documents/Code/Source/asciimatics/lib/python3.5/site-packages/asciimatics-1.5.0-py3.5.egg/asciimatics/screen.py", line 1445, in _change_colours
TypeError: write() argument must be str, not bytes
(… with the exception of not_curses.py
, which gives me “ImportError: No module named 'blessed'.”)
I understand that explaining some of this may be beyond the scope of your own interests in this package. That's fine, and your perogative 😋; feel free to close this if so … but adding some more-newcomer-friendly instructions to the README might be worthwhile!
(Unrelated side-note: I found you via being featured on the <asciinema.org> landing-page!)
I can't manage to find a way to stop screen.play(scenes) to play the list indefinitely.
I dont want the user to have to press x or q to exit the animation .
I think i have missed something in the doc .
Can you help me ?
I've just found out about https://github.com/chjj/blessed. This is a node.js library that aims to provide a similar high-level API to terminals as asciimatics. It has some neat extra features that it would be good to add.
The most obvious is the background colour highlighting that it puts on the main page demo. This provides a mechanism for painting the background with a new solid colour or a 50% linear combination (of the RGB colour tuples) of the existing BG colour and the highlight colour.
Currently, asciimatics only supports mouse click events. Assuming most *NIX terminals are like xterm, drag operations should be possible too. Windows can definitely do them.
The idea would be to add more flags to the mouse event type to clarify the mouse button up/down and movement, allowing users to detect drag an drop operations.
This is a pure Python package and uses packages that already support Python 3. How hard can it be? :-)
Request from newsgroups to reset full console state on exiting on Windows.
Executing any sample program results in a high CPU usage for me. This differs from program to program, e.g. 256colour.py
is ~21% CPU, fire.py
is at ~68% CPU, contact_list.py
at 41% CPU.
I'm using Archlinux, asciimatics 1.6.0, python3, my CPU is an Intel Core i5-2410M. On better CPU's the percentage surely will be lower, but I think that a static TUI should not consume that much.
Is this expected? Asciimatics looks very promising to me, but sadly the high cpu load makes it unusable for me.
Wouldn't it be nice to be able to plumb keyboard (and mouse?) events down to the effects so that they could act dynamically on user input?
Probably just need to pass any input from the Screen down through the Scene to any interested Effects. Could be an event registration model, or possibly mandatory on all Effects (with a simple NOOP base method).
There are some aspects of the design that should be documented in a little more detail, but they don't naturally fall in the user guide. For example:
This should be fleshed out into a proper developer guide.
Hi, I am in the process of teaching my daughter python, She loved your ascii demos and now I want to get her started on some basic ascii graphics, with a view to building up towards the more complex demos, once I understand them myself!
The problem is I am finding it quite difficult to extract basic functionality for her while hiding complexity. For example how to print out a character or string in 256 colours without invoking colour palettes etc, how to do basic key and mouse events.
What would be ideal, is an ascii animation demo, that does not use all the built in classes you created, but more of the primitive functions, so she is learning the basics without having to go down as far as win32 calls!
I am on Windows.
I would greatly appreciate any ideas you have on this.
The Canvas API is identical to the Screen API, so that any Effect can be embedded in a Frame. All that is needed is some adapter layer - e.g. a new widget type to allow any Effect to bre reproduced (and limited to) the Frame.
Looks like the UI section of the project is quite popular... Can I add some more useful widgets? Looking around, some candidates are:
Just installed asciimatics on windows 10 and i get error on all the examples i try.
I did pip install asciimatics and Everything Went fine but when i tried the examples out i get lots of errors i dont know if i am missing something.
the error i get is. its almost the same in all the examples.
Traceback (most recent call last):
File "C:\Users\xzenon\Desktop\asciimatics-master\asciimatics-master\samples\pacman.py", line 532, in <module>
Screen.wrapper(demo)
File "C:\Users\xzenon\AppData\Local\Programs\Python\Python35-32\lib\site-packages\asciimatics-1.6.0-py3.5.egg\asciimatics\screen.py", line 988, in wrapper
unicode_aware=unicode_aware)
File "C:\Users\xzenon\AppData\Local\Programs\Python\Python35-32\lib\site-packages\asciimatics-1.6.0-py3.5.egg\asciimatics\screen.py", line 897, in open
None))
pywintypes.error: (6, 'CreateFile', 'Referensen (handle) är felaktig.')
The README says the library can get cursor position, but nothing in the docs or example explicitly shows where I can get it.
If not the position of the cursor, at least the x, y position of the latest output printed to the screen. Thanks.
Hi,
As per title, the mouse events gets inhibited in Win XP when QuickEdit mode is active.
It should be possible to inihibit this behavior programmatically through [get/set]ConsoleMode and ENABLE_QUICK_EDIT_MODE. Possibly this needs to be done before entering the main loop and should set it back on exit. A big plus would be to enable/emulate clipboard events during the lack of quick edit mode.
BTW: thanks for sharing such an awesome project :-)
Wouldn't it be nice if this could run in any operating system?
Support for curses and blessed should mean any Linux or OSX system should be fine (with a little testing). Windows requires extra work - maybe using colorama?
Actually it doesn't work with the latest release of PyPy2 (PyPy2 v5.6.0) because of (now resolved) https://bitbucket.org/pypy/pypy/issues/2425/str-error-from-future-module-in-pypy2, but works with latest trunk release http://buildbot.pypy.org/nightly/trunk/ .
Just wanted to inform you :)
I was just running the samples and this fails on Ubuntu 15.04 with Python 3.4.
It appears there are two problems (both in screen.py):
I am using guake, and zsh for the terminal, though I had the same issue in gnome terminal as well.
I attempted to patch, and got it partially working by adding .decode('utf-8') calls to all the contents of stdout.write (i.e. stdout.write(some_content.decode('utf-8')) ) but there were still some oddities in images.py with trailing escape sequences getting converted to strings instead of control characters.
Unfortunately I dont have time to look into this, so just wanted to log a quick issue in case it was something straight forward to correct.
I have downloaded Asciimatics using pycharm with required dependencies,like pillow and future. I tested this on Python 3.3.5 and 3.5, but the test code from https://github.com/peterbrittain/asciimatics doesn't work. There are errors:
X:\Python33\python.exe C:/Users/Sasha/PycharmProjects/untitled/main.py
Traceback (most recent call last):
File "C:/Users/Sasha/PycharmProjects/untitled/main.py", line 20, in <module>
Screen.wrapper(demo)
File "X:\Python33\lib\site-packages\asciimatics\screen.py", line 825, in wrapper
info = old_out.GetConsoleScreenBufferInfo()
pywintypes.error: (6, 'GetConsoleScreenBufferInfo', 'Nieprawidłowe dojście.')
It may be a problem with my configuration or perhaps how I am using your package, but when I attempt to run an asciimatics program, the text color of my terminal is switched from green to white, and I have to manually switch it back after I'm done playing with asciimatics.
It would be nice if this could be automated. If it is not convenient for asciimatics to reset the colors, could/does the package perhaps expose functions for detecting and setting the text color of the terminal? Or does it do so already and I just have some kind of configuration issue?
To clarify, I am referring to the text color of my shell when asciimatics is not running. Before running asciimatics, the text color is green; After running a my asciimatics program, it is white. I would like for it to remain green.
Is it possible to use asciimatics as a progress bar placeholder? What I mean is say I have
status = GetActivityStatus() #returns True when done
while not status
#show asciimatics display
status = GetActivityStatus()
#When the loop exits the asciimatics display is exited automatically
I can't seem to figure out if this is possible from the examples.
Thanks!
It's about time this project had some automated tests. Things to consider are:
Probably should use https://travis-ci.org for the tests.
How can this be achieved without using Rainbow or FigletText and only using screen.paint or screen.print with color maps?
I've noticed unexpected behaviour while writing a program that uses asciimatics. This behavior can be reproduced easily enough using samples/forms.py
.
If you comment out all the effects except for DemoFrame
so that it effects
is equal to
effects = [
#Julia(screen),
#ClockFrame(screen, 0, 0),
#ClockFrame(screen, screen.width - 26, 0),
#ClockFrame(screen, 0, screen.height - 13),
#ClockFrame(screen, screen.width - 26, screen.height - 13),
DemoFrame(screen),
]
And then run file.
If you hit enter on a Text or Radio widget, it will reset all the form data, which is just about the only thing I'm not expecting enter to do.
This does not reproduce when there is another effect in addition to the Frame
object. So right now I just have one Clock
widget hidden behind my form to stop this. :)
The data resets itself even if I remove the Reset
button, method as well.
This applies to me on asciimatics 1.5.0 and latest git as well as python 2.7 and 3.
Thanks Peter, for your work.
It would be good to write up some tutorials at this point. Suggested topics would be:
When trying to run the forms.py example, I get this error:
Traceback (most recent call last):
File "forms.py", line 2, in <module>
from asciimatics.widgets import Frame, TextBox, Layout, Label, Divider, Text, \
ImportError: No module named 'asciimatics.widgets'
has a win32console (part of PyWIn32) dependency.
As per title, the PEP8 suggested way of determining the version of your package within Python, i.e. by setting the __version__
variable in the package namespace, is not present. Since you seems to be relatively diligent with the git tagging, I would suggest you looking into the setuptools_scm
package.
If you want, I can submit a patch with a solution similar to what I normally use in my projects (see e.g. https://bitbucket.org/norok2/hdu ), where I basically let setuptools_scm automagically determine the version from git tags, unless I set it manually for some reasons in setup.py
and then update the corresponding __version__
variable in a previously specified file, usually __init__.py
.
It's all well and good having an animated scene, but wouldn't it be nice to provide a clean way to get a still image that could be re-used elsewhere.
Options could range from just a simple ASCII string from a renderer to a full colour coded image suitable for display in the current terminal.
Hello,
I'm a little new to python, and trying to figure something out. I was wondering if you could give more examples of the KeyboardEvent class. Specifically, I was looking to generate an animation on any type of key press, such as a firework. Thanks!
Explained on stack, but would love to get this fixed.
After several new releases and extra features, there are several bits of the original API that jar a little and need removing.
TBC...
I've deliberately avoided extended character sets so far as this gets into a whole heap of encoding/decoding pain. However, it might be that UTF-8 does the trick now, though, and I could move to full unicode.
Support for UTF8 in Linux and OSX looks pretty well established. However, Windows support is suspect. Although there is codepage 65001, it would appear the glyphs are very limited. More investigation required...
Just giving you a heads up that it would be nice to know that you also need to install future, pillow and pyfiglet to get the demonstration working.
Collecting setuptools_scm
/usr/local/lib/python3.5/site-packages/pip/vendor/requests/packages/urllib3/util/ssl.py:318: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#snimissingwarning.
SNIMissingWarning
Downloading setuptools_scm-1.11.1-py2.py3-none-any.whl
Installing collected packages: setuptools-scm
Successfully installed setuptools-scm-1.11.1
[email protected]/root/scherbi # pip3.5 install asciimatics
Collecting asciimatics
Using cached asciimatics-1.7.0-py2.py3-none-any.whl
Requirement already satisfied (use --upgrade to upgrade): future in /usr/local/lib/python3.5/site-packages (from asciimatics)
Requirement already satisfied (use --upgrade to upgrade): pyfiglet>=0.7.2 in /usr/local/lib/python3.5/site-packages (from asciimatics)
Requirement already satisfied (use --upgrade to upgrade): Pillow>=2.7.0 in /usr/local/lib/python3.5/site-packages (from asciimatics)
Collecting pypiwin32 (from asciimatics)
Using cached pypiwin32-219.zip
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "", line 1, in
File "/tmp/pip-build-3_afj4p1/pypiwin32/setup.py", line 121
print "Building pywin32", pywin32_version
^
SyntaxError: Missing parentheses in call to 'print'
Time to revive another "old skool" demo... The plasma!
As described in http://lodev.org/cgtutor/plasma.html what we need is the sum of a set of sinusoidal functions and a changing colour palette.
Not everyone wants to hand full responsibility for application scheduling over to asciimatics. It would be good if I could provide a simple API to allow integration with any other framework.
Rather than provide custom versions of Screen.play() for every framework out there, it's probably better to provide a state recording mechanism inside the Screen and a simple API to refresh the current Scene - e.g. Screen.draw_one_frame().
The other frameworks then simple need to schedule this on a regular basis - ideally every 50ms.
Need a public space for suggestions of new effects... Just use issue list in github or some other site?
At the lowest level, the Screen class enforces a refresh() before it will draw anything. This is irritating for people who just want to do some simple drawing. Consider providing 2 modes of operation for the class:
Some interesting decisions need to be made in both cases:
It feels like these may behighly related, but ultimately different class implentations...
I like that matrix effect: https://asciinema.org/a/19942
but where is the code for it?
It would be nice to be able to confirm other working platforms, including Mac, CygWin and some other UNIX flavours.
I was trying test some of samples you provide, but when I try to run contact_list.py
I get the following:
└> python contact_list.py
Traceback (most recent call last):
File "contact_list.py", line 1, in <module>
from asciimatics.widgets import Frame, ListBox, Layout, Divider, Text, \
ImportError: No module named 'asciimatics.widgets'
The same happens if I try from the terminal:
└> python
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from asciimatics.widgets import Frame
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named 'asciimatics.widgets'
>>>
Am I doing something wrong?
If I run screen.print_at('hello', 0, 0)
and then update the line to screen.print_at('drop', 0, 0)
, the output would be dropo
since the 'o' had already been printed.
What is the best way to clear the line or the content? Overwrite it with whitespace before rendering the new content, or is there a method I'm not aware of? (I tried calling screen.clear()
), but if I wanted to do anything with key strokes--like backspace, for example--the response rate is janky.
When I try and get input for different control codes it seems only some work. For example ctrl+z works fine but if I try to input ctrl+s my program acts as if nothing has happened. I'm not sure if I'm just using the tool incorrectly or if control codes aren't entirely supported as of yet, but, any help would be great.
example code I used for testing:
from asciimatics.screen import Screen
import asciimatics
def mTest(screen):
while True:
event = screen.get_event()
if type(event) == asciimatics.event.KeyboardEvent:
screen.print_at(' '*25, 0, 0)
screen.print_at(str(event), 0, 0)
if event.key_code == 26:
screen.print_at('ctrl+z', 0, 1)
if event.key_code == 19:
screen.print_at('ctrl+s', 0, 2)
screen.refresh()
Screen.wrapper(mTest)
Asciimatics does not detect when the screen resizes and so hits curses errors as it tries to access invalid co-ordinates. It should detect the resizing and recalculate the screen/effects.
I using asciimatics 1.5.0.post1 in python 3.4.3 on Windows 8 64 bit.
code
from asciimatics.effects import Cycle, Stars
from asciimatics.renderers import FigletText
from asciimatics.scene import Scene
from asciimatics.screen import Screen
def demo(screen):
effects = [
Cycle(
screen,
FigletText("ASCIIMATICS", font='big'),
screen.height / 2 - 8),
Cycle(
screen,
FigletText("ROCKS!", font='big'),
screen.height / 2 + 3),
Stars(screen, 200)
]
screen.play([Scene(effects, 500)])
Screen.wrapper(demo)
but It's not working.
Traceback (most recent call last):
File "1.py", line 20, in <module>
Screen.wrapper(demo)
File "C:\py34\lib\site-packages\asciimatics\screen.py", line 478, in wrapper
func(win_screen)
File "1.py", line 18, in demo
screen.play([Scene(effects, 500)])
File "C:\py34\lib\site-packages\asciimatics\screen.py", line 701, in play
effect.update(frame)
File "C:\py34\lib\site-packages\asciimatics\effects.py", line 63, in update
self._update(frame_no)
File "C:\py34\lib\site-packages\asciimatics\effects.py", line 180, in _update
self._screen.centre(line, y, self._colour)
File "C:\py34\lib\site-packages\asciimatics\screen.py", line 630, in centre
self.paint(text, x, y, colour, attr, colour_map=colour_map)
File "C:\py34\lib\site-packages\asciimatics\screen.py", line 654, in paint
self.print_at(text, x, y, colour, attr, bg, transparent)
File "C:\py34\lib\site-packages\asciimatics\screen.py", line 962, in print_at
self._double_buffer[y][x + i] = (c, colour, attr, bg)
TypeError: list indices must be integers, not float
Thank you. Merry Christmas.
Running the example given in the readme gives the following traceback:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\asciimatics\screen.py", line 393, in wrapper
func(win_screen)
File "<stdin>", line 13, in demo
File "C:\Python27\lib\site-packages\asciimatics\screen.py", line 560, in play
self.clear()
File "C:\Python27\lib\site-packages\asciimatics\screen.py", line 740, in clear
self._clear()
File "C:\Python27\lib\site-packages\asciimatics\screen.py", line 988, in _clear
" ", box_size, win32console.PyCOORDType(0, 0))
ValueError: Object must be a single unicode character
My setup:
I had a quick look at the FillConsoleOutputCharacter
docs, but couldn't figure out what it wanted.
Currently, when resizing the terminal/console window, the Screen doesn't update its width/height.
def demo(screen):
while True:
if screen.width < 80 or screen.height < 24:
if screen.has_resized():
# just checking:
print('needs resizing') # doesn't get called if screen is already > 80 x 24
print(screen.width) # doesn't change
print(screen.height) # doesn't change
message = 'Resize window to at least 80(w)x24(h)'
screen.print_at(message, screen.width//2 - len(message)//2, screen.height //2 -3)
else:
if screen.has_resized():
# just checking:
print('size OK') # doesn't get called if screen is < 80 x 24
print(screen.width) # doesn't change
print(screen.height) # doesn't change
screen.print_at('Resized!', 0, 0)
screen.refresh()
Screen.wrapper(demo)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.