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
. Thef_show
call triggers rendering of the form. All the reserved attributes are prepended withf_
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
andquit
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"]
(orform.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.
pip install ascii_designer
Requirements: Python >= 3, attrs
. To use the Qt toolkit you need qtpy
.
Please proceed to http://ascii_designer.readthedocs.io/en/latest/index.html
MIT License: https://github.com/loehnertj/ascii_designer/blob/master/LICENSE
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.