ASCII Designer
==============
A library that:
* creates GUI from ASCII-art (with well-defined syntax)
* maps widgets to virtual class attributes
* relieves you from the boring parts of Form building while leaving you in
control.
Did you ever design a form by scribbling something like this in your editor::
Text to transform: [ Text_ ]
Select transformation:
(x) Uppercase
( ) Lowercase
( ) Title-case
[ OK ] [ Cancel ]
... and wished that you could be done with design and start coding? Wish no longer::
from ascii_designer import AutoFrame
class TextTransformer(AutoFrame):
f_body='''
| <-> |
Text to transform: [ Text_ ]
Select transformation:
(x) Uppercase
( ) Lowercase
( ) Title-case
[ OK ] [ Cancel ]~
'''
def ok(self):
text = self.text
if self.uppercase:
text = text.upper()
elif self.lowercase:
text = text.lower()
elif self.titlecase:
text = text.title()
print(text)
self.close()
def cancel(self):
self.close()
if __name__ == '__main__':
TextTransformer().f_show()
Some comments, incidentally highlighting the features of this library:
* As you probably guessed, all the magic happens in ``AutoFrame``. The
``f_show`` call triggers rendering of the form. All the reserved attributes
are prepended with ``f_`` to get out of your way when subclassing.
* There is a **well-defined syntax** for how to get the usual widget types. In the
example you can find labels (plain text), a text box, radio buttons and normal
buttons.
* The columns are defined by the **header row** with the pipe characters. The
minus sign denotes stretching columns. (The ``<`` / ``>`` chars are just
decoration.)
* **Column-span** is easily done by having not-a-space underneath the pipe
symbol. **Row-span** can also be done by prepending subsequent cells with a
``{`` character.
* **Anchoring** is controlled by whether the cell is space-padded or not. For
example, the Text box stretches, while the cancel button is centered. The
tilde character can be used instead of a fragile trailing space.
* **Widget IDs** are automatically generated by lowercasing and whitelisting the
captions.
* If a method exists with the same name as a widget id, it is **automatically
bound** to the usually-wanted event (click in case of button, value-changed in
case of basically anything else). Oh, and ``close`` and ``quit`` are already
there for your convenience.
* Otherwise, you can retrieve and set the widget's value by using its id like
a class **attribute**.
* ``f_show()`` captures all the usual boilerplate and simply f***ing shows
the frame. It can be used for both the toplevel and additional frames.
* Also note how the class name automatically turned into the window title.
Override by setting ``.f_title``.
* The created widgets are **"raw", native widgets**. You can configure the toolkit
to use. Currently there is a Qt and a Tkinter implementation. The native
widget can accessed using ``form["widget_id"]`` (or
``form.f_controls["widget_id"]``).
The general philosophy is to not paint everything over with wrappers. Instead,
the library focuses on specific tasks - building the layout, event-/value
binding - and lets you do everything else with the API you know and (maybe) love.
INSTALLATION
------------
::
pip install ascii_designer
Requirements: Python >= 3, ``attrs``. To use the Qt toolkit you need ``qtpy``.
DOCUMENTATION
-------------
Please proceed to http://ascii_designer.readthedocs.io/en/latest/index.html
LICENCSE
--------
MIT License: https://github.com/loehnertj/ascii_designer/blob/master/LICENSE
TODO
----
Alpha-state software, mostly working.
Test coverage is lacking, politely spoken.
This is a hobby project. If you need something quick, open an issue or send a pull request.