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.