gui design with python – examples from crystallography bernhard lohkamp karolinska institute...

Post on 20-Dec-2015

228 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

GUI design with Python –examples from crystallography

Bernhard Lohkamp

Karolinska Institute

Stockholm

Sweden

7/5/10Bernhard.Lohkamp@ki.se

Coot - Who are we – why am I here?

Paul Emsley

(Oxford; everything)

Bernhard Lohkamp

(Stockholm; Python, GUI, Windows)

Kevin Cowtan (York;

crystallographic libraries & tools)

Eugene Krissinel, Stuart McNicholas, and others...

7/5/10Bernhard.Lohkamp@ki.se

COOT

Graphical (Crystallographic-Object)-Oriented Toolkit

Used in macromolecular (X-ray) crystallography

Main aims:Model buildingModel completionModel validation

Graphical, interactive, intuitive, …

7/5/10Bernhard.Lohkamp@ki.se

G(raphical) U(ser) I(nterface)GUI <-> UI Allow end users to interact with application Interface can be simple (e.g. command line) to

complex (graphical) Good UI:

IntuitiveEasy to use/learn

Note: applications with good UI are preferred to ones with inferior ones (independent of quality of application!?)

7/5/10Bernhard.Lohkamp@ki.se

What do you prefer?

>>> delete_residue(10)

7/5/10Bernhard.Lohkamp@ki.se

GUIs

Good things about GUIIntuitive (if designed properly)More efficient (e.g., putting the cursor at a particular

location)Multiple activities simultaneously

Bad things about GUIInefficient (if mis-designed)Difficult to automate (e.g. difficult to write a program

to push a button in another application)Speed

7/5/10Bernhard.Lohkamp@ki.se

The challenge of GUI programming

programming model must address the following issues:user allowed to perform different things (e.g. type a character,

type a hot-key, click on a button, resize the window, obscure the window with another application, minimize it, etc.)

program needs to adapt to different window size (and with it all its content)

Solution:event-driven modelwidget systems (controlled by a geometry manager)

Use Toolkits == TK

7/5/10Bernhard.Lohkamp@ki.se

Forms of interactionevents in context

Human Interface Device (HID)

control

Windows manager/Desktop

7/5/10Bernhard.Lohkamp@ki.se

Windowing system/hierarchy Lots of layers Not very efficient Slow (not necessary to be fast?!)

Our script (in Python): Real application

TK (in Python): glue to TK

TK Python plugin (usually in C): translate to TK calls

TK widgets (usually in C): Widget implementation

TK library (usually C): glue to windowing system

Windows managing system (e.g. X)

7/5/10Bernhard.Lohkamp@ki.se

Connect GUI with Python

Direct via script GUI design tools and

IDEs (Integrated Development Environments)GUI builderGUI to build a GUI

applicationUseful especially for larger

projectsOutput usually xml

Use directly Translate to Python script

7/5/10Bernhard.Lohkamp@ki.se

GUI modules for Python (I)(Toolkits, cross-platform) PyGTK (Gnome): Coot

TK: GTK+ (GIMP Tool Kit)Well supportedBuilder (Glade)

xml directNot native on Mac (yet)

PyQt (KDE): CCP4mg – molecular graphicsTK: Qt (“cu-te”)Licence issue?NativeBuilder (Designer)

xml->python

7/5/10Bernhard.Lohkamp@ki.se

GUI modules for Python (II)

Tk(Inter): PyMOLTK: TkTkinter Python Tk interfaceDistributed with pythonNot OOBuilder (GUI builder)

wxPython: PhenixTK: wxWidgetsBuilder (wxGlade)Native?

7/5/10Bernhard.Lohkamp@ki.se

Nomenclature/Widgets

Widget: “windowing gadget”, which means “a useful building block (gadget) to make a windowing system”.

Hierarchy (exemplified):

7/5/10Bernhard.Lohkamp@ki.se

Widget examples

Top level (independent widgets):Main windowVarious (pre-

defined) dialogs

7/5/10Bernhard.Lohkamp@ki.se

Dialogs (I)

Info (Message) dialog

Dialog box

7/5/10Bernhard.Lohkamp@ki.se

Dialogs (II)

About dialog

Assistant

7/5/10Bernhard.Lohkamp@ki.se

Dialogs (III)

Selection dialogsFilesColoursFonts….

7/5/10Bernhard.Lohkamp@ki.se

Containers/Layout

BoxesVerticalHorizontalCombined (grid, table)

Scrolled window Tabbed

widgets/notebook Frames Panes

7/5/10Bernhard.Lohkamp@ki.se

Boxed layout

7/5/10Bernhard.Lohkamp@ki.se

Tabbed window/Notebook tabs

7/5/10Bernhard.Lohkamp@ki.se

Buttons

Button Toggle button Check button Spin button Radio button Pre-defined buttons

FilesColoursFonts…

7/5/10Bernhard.Lohkamp@ki.se

Input & Entries (I)

Menu

Toolbar

7/5/10Bernhard.Lohkamp@ki.se

Menus

Submenus Icons Accelerators

7/5/10Bernhard.Lohkamp@ki.se

Context menu

Shown upon event (usually mouse click)

7/5/10Bernhard.Lohkamp@ki.se

Toolbars

Like menus but contain icons/buttons Short-cut for frequently used functions

7/5/10Bernhard.Lohkamp@ki.se

Toolbar

7/5/10Bernhard.Lohkamp@ki.se

Change

Style

7/5/10Bernhard.Lohkamp@ki.se

Text

only

7/5/10Bernhard.Lohkamp@ki.se

Text

and

Icons

7/5/10Bernhard.Lohkamp@ki.se

Toolbar

Detouch/

Handle

7/5/10Bernhard.Lohkamp@ki.se

detouched

7/5/10Bernhard.Lohkamp@ki.se

Input & Entries (I)

Combobox – spin button

Simple Entry:

7/5/10Bernhard.Lohkamp@ki.se

Input & Entries (II)

Entry:Auto-completion possible

Sliders

7/5/10Bernhard.Lohkamp@ki.se

List/Tree structures

7/5/10Bernhard.Lohkamp@ki.se

Can include: icons, buttons, …

7/5/10Bernhard.Lohkamp@ki.se

Tree-> expansion

7/5/10Bernhard.Lohkamp@ki.se

Miscellaneous widgets

Progress bar

Status bar

7/5/10Bernhard.Lohkamp@ki.se

Canvas

Drawing area Canvas/cairo drawing

(e.g. PyGoocanvas) OpenGL drawing (e.g.

PyOpenGL, PyGtkGLExt)

Can be interactive

7/5/10Bernhard.Lohkamp@ki.se

Tooltips

Pop ups with text (upon mouse over)

Helps to explore the GUI without reading help files

Use whenever you can (!?)

7/5/10Bernhard.Lohkamp@ki.se

GUI designWhat makes a good UI?

Simple Intuitive Respects the commonly accepted conventions Visually organized Native look

7/5/10Bernhard.Lohkamp@ki.se

Designing UIs

Two levels:Graphical: visual aspectEvents: Functionality

Basic blocks = widgets Making an application react to events = binding

7/5/10Bernhard.Lohkamp@ki.se

General concepts

Main loop and events Packing Showing

How to do.

7/5/10Bernhard.Lohkamp@ki.se

Main loop and events

TK mainloop:Event loop Idle until an event happens (e.g. a button is pushed, a menu

is pulled, etc.)Quit when program (GUI) finishesCan have multiple loops (count!!)

PyGTK: gtk.main() TKinter: tk.mainloop() PyQT:application.exec_()

7/5/10Bernhard.Lohkamp@ki.se

Main loop and events

Events (examples):Keyboard (key-pressed, key-released)Mouse (button-pressed, button-released, motion, wheel, …) Window/widget (resize, destroy, visibility, activate, deactivate, …)Etc.

Event modifiers (Shift, Alt, …) Events emit signals Can be connected with callbacks (functions, methods)

7/5/10Bernhard.Lohkamp@ki.se

Callbacks and signals

Callback functions/bindings: functions, methods do something when event happens (e.g. button pressed)

PyGTK:object.connect(signal_name, callback_func, func_data)def callback_func(widget, callback_data):def callback_meth(self, widget, callback_data):

Tkinter:Button(master, text="OK", command=callback)def callback_func():

PyQT:connect(widget, signal, callback_func)

7/5/10Bernhard.Lohkamp@ki.se

Synergy between objects and widgets

Variables are passed automatically within class refer to them as self.whatever No need to pass variables

Callback functionsEasy to handleNo need to define callbacks on the fly (lambda functions)

7/5/10Bernhard.Lohkamp@ki.se

Packing Add widget to container Pack widget in boxes

PyGTK:container_widget.add(widget)box_object.pack_start(child, expand, fill, padding)

Tkinter:object.pack(various_options)

PyQT:Layout.addWidget(widget)

7/5/10Bernhard.Lohkamp@ki.se

Packing

Homogeneous (equal space for everyone) HBox(True/False, 0)

Expand, fill box.pack(expand=, fill=)

7/5/10Bernhard.Lohkamp@ki.se

Showing Widgets itself do not show (neither do they do anything else ->

connect signals!) Need to show every (!) widget Can hide widgets Usually collective show for all

PyGTK:widget.show()widget.hide()widget.show_all()

Tkinter:Done via mainloop

PyQT:widget.show()widget.hide()

7/5/10Bernhard.Lohkamp@ki.se

Simple example

GUI command input

Schematic in terms of widgets

window

VBox

HBoxLabel Entry

ScrolledWindowTextBuffer

Button

7/5/10Bernhard.Lohkamp@ki.se

Simple example- make window

# import gtk module

import gtk

# create a main window

window = gtk.Window(gtk.WINDOW_TOPLEVEL)

# set the title

window.set_title("Coot Python Scripting")

# set some more properties (if we wish)

window.set_default_size(400,250)

7/5/10Bernhard.Lohkamp@ki.se

Simple example- create widgets

# create other needed widgets: boxes, label, entry, …

vbox = gtk.VBox(homogeneous=False, spacing=0)

hbox = gtk.HBox(False, 0)

label = gtk.Label("Command: ")

entry = gtk.Entry()

scrolled_win = gtk.ScrolledWindow()

text = gtk.TextView()

textbuffer = text.get_buffer()

close_button = gtk.Button(" Close ")

7/5/10Bernhard.Lohkamp@ki.se

Simple example- pack it in

# add vbox in window

window.add(vbox)

# pack the hbox and pack into the vbox

hbox.pack_start(child=label, expand=False, fill=False, padding=0)

hbox.pack_start(entry, True, True, 0)

vbox.pack_start(hbox, False, False, 5)

window

VBox

HBoxLabel Entry

ScrolledWindowTextBuffer

Button

7/5/10Bernhard.Lohkamp@ki.se

Simple example- pack it in

# pack the scrolled text area

scrolled_win.add(text)

vbox.add(scrolled_win)

# and finally the button

vbox.pack_end(close_button, False, False, 5)

window

VBox

HBoxLabel Entry

ScrolledWindowTextBuffer

Button

7/5/10Bernhard.Lohkamp@ki.se

Simple example- show it

# show everything connected to the window

window.show_all()

# run the main loop

gtk.main()

7/5/10Bernhard.Lohkamp@ki.se

Simple example- making it functional (close button)

Does not perform any function (yet) Main loop never stops connect callbacks and signals

# connect close_button (no further args)

close_button.connect(“clicked”, close_callback)

# define callback: destroy window, quit gtk loop

def close_callback(widget):

window.destroy()

gtk.main_quit()

7/5/10Bernhard.Lohkamp@ki.se

Simple example- making it functional (destroy window)

Closing window does not finish gtk loop Deal with delete event

# connect delete_event (two args, but no extra)

window.connect(“delete_event”, delete_event_cb)

# define callback: quit gtk main loop

def delete_event_cb(widget, event):

gtk.main_quit()

7/5/10Bernhard.Lohkamp@ki.se

Simple example- making it functional (entry)

# do something with entry when enter is pressed

entry.connect(“activate”, do_callback)

# what to do

def do_callback(widget):

entry_text = widget.get_text()

print “input is”, entry_text

# erase the entry

widget.set_text(“”)

# do something with the text,

# e.g. put in text

# scrolled window

end = textbuffer.get_end_iter()

textbuffer.insert(end, str(entry_text + "\n"))

7/5/10Bernhard.Lohkamp@ki.se

Glade (GUI builders)

Editor

Properties

Inspector

Palette

7/5/10Bernhard.Lohkamp@ki.se

Glade

Output xml file Two different ‘formats’ (libglade, builder)

==> my_test3.libglade <==

<?xml version="1.0"?>

<glade-interface>

<!-- interface-requires gtk+ 2.16 -->

<!-- interface-naming-policy project-wide -->

<widget class="GtkWindow" id="window1">

<child>

<widget class="GtkVBox" id="vbox1">

<property name="visible">True</property>

<property name="orientation">vertical</property>

==> my_test3.glade <==

<?xml version="1.0"?>

<interface>

<requires lib="gtk+" version="2.16"/>

<!-- interface-naming-policy project-wide -->

<object class="GtkWindow" id="window1">

<child>

<object class="GtkVBox" id="vbox1">

<property name="visible">True</property>

<property name="orientation">vertical</property>

7/5/10Bernhard.Lohkamp@ki.se

Connect to python script Keep GUI/widgets and events separate Useful for larger projects (easy to add, remove, clean)

import pygtk, gtk

builder = gtk.Builder()

builder.add_from_file(“my_file.glade”)

# get the main window and connect event

window = builder.get_object(“window1”)

window.connect("destroy", gtk.main_quit)

# show and run

window.show_all()

gtk.main()

7/5/10Bernhard.Lohkamp@ki.se

Glade – connect more signals

Use automatic connection

# dictionary of callbacks (name of signal,

# callback function)

dic = { "on_button1_clicked" : button1_cb,

"on_button2_toggled" : button2_cb,

"on_window1_destroy" : gtk.main_quit }

# define some callbacks

def button1_cb(widget): print “button 1 pressed”

def button2_cb(widget): print “button 2 toggled”

# connect the signals

builder.connect_signals(dic)

7/5/10Bernhard.Lohkamp@ki.se

(lib)glade

same principle (as for gtk.Builder) slightly different syntax

7/5/10Bernhard.Lohkamp@ki.se

The higher end implementationsCombining C/C++/Python/GTK

Python

7/5/10Bernhard.Lohkamp@ki.se

Pythoninterface

Pythonfunctions

SWIG

Coot and Python

C(++)-functions

Python functions(objects)

Gtk+ objects(graphics)

call

return value

Pythonscripting functions

7/5/10Bernhard.Lohkamp@ki.se

Main Menubar

Main Menubar

7/5/10Bernhard.Lohkamp@ki.se

Addition of individual menu items

Accessing existing menus

7/5/10Bernhard.Lohkamp@ki.se

Main Toolbar

Main Toolbar

7/5/10Bernhard.Lohkamp@ki.se

Extra toolbuttons

Main Toolbar

Pop-up menu to manage toolbuttons

7/5/10Bernhard.Lohkamp@ki.se

Some hints for your own design:Organize

7/5/10Bernhard.Lohkamp@ki.se

Some hints for your own design:group related items

7/5/10Bernhard.Lohkamp@ki.se

Some hints for your own design:keep it simple

7/5/10Bernhard.Lohkamp@ki.se

Some hints for your own design:don’t reinvent the wheel – keep conventions

Use standard menu items Use standard icons Carefully choose colours:

colour blindness!!

7/5/10Bernhard.Lohkamp@ki.se

Further information on GUI/Python/TKs GUI

http://www.guidebookgallery.org/index http://www.asktog.com/basics/firstPrinciples.html http://web.cs.wpi.edu/~matt/courses/cs563/talks/smartin/int_design.html http://www-01.ibm.com/software/ucd/designconcepts.html http://library.gnome.org/devel/hig-book/stable/intro.html.en

PyGTK, Glade http://www.pygtk.org/ http://glade.gnome.org/ http://live.gnome.org/Glade/Tutorials http://www.micahcarrick.com/12-24-2007/gtk-glade-tutorial-part-1.html

PyQT http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/pyqt4ref.html http://www.commandprompt.com/community/pyqt/ http://www.cs.usfca.edu/~afedosov/qttut/

7/5/10Bernhard.Lohkamp@ki.se

Acknowledgements

Paul Emsley Kevin Cowtan Eleanor Dodson Keith Wilson

BBSRC & CCP4 funding

Libraries, dictionaries Alexei Vagin, Eugene Krissinel, Stuart McNicholas Dunbrack, Richardsons Coot Builders and Testers William Scott, Ezra Peisach York YSBL, Dundee, Glasgow (early adopters) Coot Mailing List subscribers

http://www.biop.ox.ac.uk/coot/

or

Google: Coot

or

http://www.ysbl.ac.uk/~lohkamp/coot

7/5/10Bernhard.Lohkamp@ki.se

DEMO?

7/5/10Bernhard.Lohkamp@ki.se

Hierarchy

7/5/10Bernhard.Lohkamp@ki.se

top related