Blind User Interface - the interface you can design with your eyes closed
Blind User Interface (BUI) is meant to be a simple toolkit to design user interfaces with a Pythonic syntax. Having been created by a blind user, it gives a lot of importance to accessibility and compatibility with screen readers, while offering a comfortable user interface that anyone can use. However, this restriction doesn’t imply you cannot (and should not) create complex or really beautiful user interfaces with BUI. You should and you can. You might consider helping this project, however, to help create more elaborate interfaces should the need arise.
BUI relies on several core principles:
- An interface should not break or require any change in code when porting to a new platform. Thus, BUI is compatible at least with Linux, Mac OS X and Windows platforms.
- A GUI toolkit perfectly accessible on Windows might break accessibility on Linux or Mac OS X. Therefore, BUI might choose a different toolkit depending on the user’s environment.
- Design and control should be separated: no more code to create interfaces should be necessary. Designing beautiful interfaces is, after all, a work for the designers, not for the developers. Developers should focus on the user interactions (that is, how to handle a mouse press on this button, or what to do if some text is typed in this field).
- A graphical user interface should be easy to test (in unittests for instance). The stability of the user interface should be a core concern of the developer.
These simple concepts make for an interesting (and inovative, to some extent) approach to creating interfaces with BUI.
To install BUI, you should simply run
pip install bui
BUI is currently supported on Windows and will install wxPython. Other toolkits and platforms will be supported with some help and time.
Here is a basic usage of BUI. This example is briefly explained just below. To test this script, place it in any file and run it with Python, having installed BUI and a supported GUI toolkit:
from bui import Window, start class HelloBUI(Window): """Class to represent a basic hello world window.""" layout = mark(""" <window title="A BUI demonstration"> <menubar> <menu name="File"> <item>What is it?</item> <item>Quit</item> </menu> </menubar> <button x=2 y=2>Click me!</button> <text x=3 y=3 id=report>Report</text> </window> """) def on_click_me(self): """When the 'Click me!' button is pressed.""" self["report"].value = "The button was clicked!" def on_quit(self): """When the user press the quit menu item in the File menu.""" self.close() # Keyboard shortcuts def on_press_alt_f4(self): """When the user presses Alt + F4.""" self.close() # Linking an alias to a method is so simple on_press_ctrl_q = on_press_alt_f4 start(HelloBUI)
That’s it. This little code will generate a window with:
- A menu bar, containing only one menu (File) with different menu items.
- A button in the center of the window, called “Click me!”.
- A text field below and to the right of this button where the text will be updated when the button is clicked.
In terms of code, here is what we do:
- We import the
buipackage, most specifically the Window class and the
startfunction. Usually you won’t need to import more than the Window class, except for a window meant to open with your program.
- We create a class,
HelloBUI, inheriting from Window. So far, this is all very standard.
layoutclass attribute deserves some explanation. You can see it contains a multiline string. In this string is defined the window layout, that is, how it should appear. It contains something like simple HTML syntax, though it’s not the HTML you will find on websites. The syntax is, it is hoped, somewhat easy to read.
- Below is our actual window, in the
windowtag. This one might be trickier: we define the window with a size (both width in columns and height in rows). You can picture the end result as a grid. On this grid we will place our widgets in the window. You can choose a big or small grid (it will give you more power to place widgets with a greater precision, but the size will always be relative to the window and screen size as defined by the operating system).
- The menu bar is defined first on this window, with its single menu (File) and a set of menu items in this menu.
- In the window, we have two widgets: a button and a text field.
yare given to place the widget in this grid. Note that
x=0, y=0is the upper-left corner of the window, thus,
x=2 y=2with a window of 5 colums and 5 rows will be in the middle. And
x=3 y=3will be a bit below and to the right of this widget.
- Notice we wrap this multi-line string in a call to
mark(). This function is only available in a class inheriting from Window and only serves for debugging purposes, to show the error with greater accuracy (and tell you where it went wrong).
- That’s it for the window layout. The next methods are controls (event handlers). They are written by developers and are meant to intercept user actions (like “this button was clicked”).
- Our first control method is
on_click_me. BUI will automatically bind that to the action “the ‘click me!’ button was clicked”. The process deserves its own documentation. For the time being, suffice it to say that when the user clicks on the button, this method is called with no argument.
- The only thing it does is update the text field. The
operator is used to retrieve the widget of a given ID (here,
"report"). We then update it (that is, change its value attribute). So that when the user clicks on this button, the text field will be updated.
- The second method,
on_quit, is called when the users clicks on the Quit menu item in the File menu. Again, BUI is smart enough to establish the connection. Should it have its doubts, it will ask you to clarify in plain English and will not be as mean as not linking control methods that have no apparent meaning to it.
- In this method we just call the
closemethod of the window to terminate.
on_press_alt_f4is a control method that will be called whenever the user presses ‘Alt + F4’ when the window is focused. We close it. Notice that we include the key names in the method name, which tends to be much easier to read and link.
on_press_ctrl_qis a simple alias for the previous method. So when the user presses CTRL + Q, it’s as if she had pressed ALT + F4 or clicked on “Quit”.
- This was a class, we give it to
startwhich will be responsible for starting a new window, try to find a toolkit it can use and then use it.
Notice that most of the code is actually used by our window layout. You can (and maybe should) place the HTML window layout in a separate file, so that designers can edit it wihout seeing and worrying about your code. On your side, you don’t really need to know how the window is designed, as long as you know the controls to interact with users.
BUI’s documentation can be found here, or in the docs folder in the repository itself :
- Supported infrastructure
- Layout syntax
- Data models
Blind User Interface is available under the terms of the BSD Public License (v3). In short, you can use this code for whatever reason, provided you keep the copyright identifying this code as from BUI. Apart from that, you can use this code for whatever purpose, including to design commercial software. You can find the full terms by reading the LICENSE file.