Eagle Introduction

Eagle is an abstraction layer atop Graphical Toolkits to make GUI programming as easy as possible. Eagle reaches this by narrowing what's possible to do and providing high level components with easy to use API.

Eagle doesn't enable you to create every kind of GUI, it provides resources to create windows with 5 areas (left, right, top, bottom and center), each one provides automatic scrollbars and lay out components in a sensible way: left, right and center provides vertical scrollbars and vertical layout, while top and bottom uses horizontal. Eagle calls each window an application (App).

Each App provides a preferences window, a window that is modal to the application window and will save and restore its components values automatically together with other App persistent components.

Every component have an identification name (id) and can be reach by this, so you can avoid global variables to access components. Each id have the scope of the application it's inside and thus one component can be in just one App. You may access components instances with get_widget_by_id( id, app_id ), app_id may be omitted, the first declared application will be used, this is useful when you have just one, since you can save some typing. Some components may not receive an id (App, customized buttons like CloseButton) since you usually will not use they name directly (probably they already do everything, like QuitButton that quits program), these will be named sequentially. Every widget can be accessed using Python's dict syntax.

Every input component can be persisted, that is, its contents will be saved to a file after they changed and will be loaded from this file automatically when the application starts. Components that are in App preferences will be marked persistent automatically, other components should be marked with the parameter persistent=True.

Every input or output component have a common API to set/get value, you may use the set_value( new_value ) or get_value() methods if you like Object Oriented Programming or you may use set_value( component_id, new_value, app_id ) or get_value( component_id, app_id ) if you don't. Eagle has special support for input and output components if using the dict-like syntax: it already does set_value or get_value as appropriated:

# It's easier to write
value = my_app[ "my_widget" ]
my_app[ "my_widget" ] = value

# instead of
my_widget = get_widget_by_id( my_app, "my_widget" )
value = my_widget.get_value()
my_widget.set_value( value )

Example of dict-like access.

Input and Buttons components provide a callback to notify some action. Input calls back the provided function with app_id, component_id and value as parameters when they contents changed, while buttons calls back when with app_id and component_id when clicked. Eagle, different from toolkits like GTK, Qt, Tk and others doesn't provide various callbacks for the same component, like double-clicked or mouse-over, just the callback that makes more sense. This makes programming much easier and GUI more consistent usability-wise. There is, however, one exception: App, it provides 2 callbacks: one to notify that data changed (if you use the same callback to handle every input component, you may use this and avoid some typing!) and other that is called before the App closes.

Eagle show room

Eagle show room.

Eagle show room annotated

Eagle show room annotated.

Installing Eagle

Eagle code is available at SVN repository: http://code.gustavobarbieri.com.br/eagle/

Grab it with: svn co http://code.gustavobarbieri.com.br/eagle cd eagle

Then use Python's distutils to install: python setup.py install

Hello World!

Let's create a simple program, it will present the message Hello World as a button, that when clicked will print the same message to standard output and then quit the program.

from eagle import *

def my_callback( app, widget ):
   print "Hello World"
   quit()

App(
   title="Hello World",
   center=Button(
      id="button",
      label="Hello World",
      callback=my_callback,
      )
   )

run()

helloworld.py

The first thing we must do is import symbols from the eagle module. For sake of simplicity, we import every symbol.

Then we define a python function that get two parameters, a reference to the application and the widget that was the source of the event. This function is really simple, it prints the message and then calls Eagle's quit() function, that stops the main event loop.

Next we declare the user interface, providing it a title and a widget to the center position. This widget is the Button class, that takes as arguments an id, label and the function to call back when the button is pushed.

We are almost done, just need to enter the main event loop and have Eagle to deliver actions based on defined callbacks.

You may check API of these elements at http://www.gustavobarbieri.com.br/eagle/docs/api/:

Multiple widgets

As already said, you can add multiple widgets to each of 6 areas (left, right, center, top, bottom and preferences). Just use a Python list or tuple!

from eagle import *

App(
   title="Look Mamma, Multiple Widgets!",
   center=(
      Button( id="b1", label="Button 1" ),
      Button( id="b2", label="Button 2" ),
      )
   )

run()

multiplewidgets.py

User Input

Almost every program needs to communicate with user. Ealge is optimized for this, making this common task a snap!

from eagle import *

def user_input( app, wid, text ):
   print app, wid, text

def set_text( app, wid ):
   app[ "entry" ] = "some text"

App(
   title="Type something or press the button",
   center=(
      Entry( id="entry", label="Input:", callback=user_input ),
      Button( id="button", label="Change Text", callback=set_text ),
      )
   )

run()

userinput.py

Canvas: The Drawing Areas

Eagle was born to help to create GUIs for Computer Graphics and Image Processing software, so it have an easy-to-use canvas where you can draw.

from eagle import *

def mouse_callback( app, wid, button, x, y ):
   if mouse_callback.last_point is not None:
      x0, y0 = mouse_callback.last_point
      app[ "canvas" ].draw_line( x0, y0, x, y, "red" )
   mouse_callback.last_point = ( x, y )
mouse_callback.last_point = None

def draw_image( app, wid ):
   img = Image( filename="img.png" )
   app[ "canvas" ].draw_image( image=img, x=10, y=10 )

App(
   title="Type something or press the button",
   center=(
      Canvas( id="canvas", label="Canvas:", width=800, height=600, callback=mouse_callback ),
      Button( id="button", label="Draw Image", callback=draw_image ),
      )
   )

run()

canvas.py

This example requires a further explanation because of the weird mouse_callback. What we do there is to remember the last draw point using a function attribute last_point. Remember that in Python everything is an object, so functions, then you can use an attribute, like with other objects, and simulate static variables (in C).

About This Document

This document was written by Gustavo Sverzut Barbieri and is licensed under Creative Commons - Attribution/Share Alike.

Grab most recent version at:

http://www.gustavobarbieri.com.br/eagle/docs/eagle.html