GUI_design

advertisement
GUI design with Python –
examples from crystallography
Bernhard Lohkamp
Karolinska Institute
Stockholm
Sweden
Coot - Who are we – why am I here?
Paul Emsley
(Oxford; everything)
Bernhard Lohkamp
(Stockholm; Python, GUI, Windows)
Kevin Cowtan (York;
crystallographic libraries & tools)
Bernhard.Lohkamp@ki.se
Eugene Krissinel, Stuart McNicholas, and others...
7/5/10
COOT
 Graphical
(CrystallographicObject)-Oriented Toolkit
 Used in macromolecular
(X-ray) crystallography
 Main aims:
 Model building
 Model completion
 Model validation
 Graphical, interactive,
intuitive, …
Bernhard.Lohkamp@ki.se
7/5/10
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:
 Intuitive
 Easy to use/learn
 Note: applications with good UI are preferred to ones
with inferior ones (independent of quality of
application!?)
Bernhard.Lohkamp@ki.se
7/5/10
What do you prefer?
>>> delete_residue(10)
Bernhard.Lohkamp@ki.se
7/5/10
GUIs
 Good things about GUI
Intuitive (if designed properly)
More efficient (e.g., putting the cursor at a
particular location)
Multiple activities simultaneously
 Bad things about GUI
Inefficient (if mis-designed)
Difficult to automate (e.g. difficult to write a
program to push a button in another application)
Speed
Bernhard.Lohkamp@ki.se
7/5/10
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 model
 widget systems (controlled by a geometry manager)
 Use Toolkits == TK
Bernhard.Lohkamp@ki.se
7/5/10
Windows manager/Desktop
Forms of interaction
events in context
 Human Interface
Device (HID)
control
Bernhard.Lohkamp@ki.se
7/5/10
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)
Bernhard.Lohkamp@ki.se
7/5/10
Connect GUI with Python
 Direct via script
 GUI design tools and
IDEs (Integrated
Development
Environments)
 GUI builder
 GUI to build a GUI
application
 Useful especially for larger
projects
 Output usually xml
 Use directly
 Translate to Python script
Bernhard.Lohkamp@ki.se
7/5/10
GUI modules for Python (I)
(Toolkits, cross-platform)
 PyGTK (Gnome): Coot
 TK: GTK+ (GIMP Tool Kit)
 Well supported
 Builder (Glade)
 xml direct
 Not native on Mac (yet)
 PyQt (KDE): CCP4mg –
molecular graphics
 TK: Qt (“cu-te”)
 Licence issue?
 Native
 Builder (Designer)
 xml->python
Bernhard.Lohkamp@ki.se
7/5/10
GUI modules for Python (II)
 Tk(Inter): PyMOL
 TK: Tk
 Tkinter Python Tk
interface
 Distributed with python
 Not OO
 Builder (GUI builder)
 wxPython: Phenix
 TK: wxWidgets
 Builder (wxGlade)
 Native
?
Bernhard.Lohkamp@ki.se
7/5/10
Nomenclature/Widgets
 Widget: “windowing gadget”, which means “a useful
building block (gadget) to make a windowing system”.
 Hierarchy (exemplified):
Bernhard.Lohkamp@ki.se
7/5/10
Widget examples
 Top level
(independent
widgets):
 Main window
 Various (predefined) dialogs
Bernhard.Lohkamp@ki.se
7/5/10
Dialogs (I)
 Info (Message) dialog
 Dialog box
Bernhard.Lohkamp@ki.se
7/5/10
Dialogs (II)
 About dialog
 Assistant
Bernhard.Lohkamp@ki.se
7/5/10
Dialogs (III)
 Selection dialogs
 Files
 Colours
 Fonts
 ….
Bernhard.Lohkamp@ki.se
7/5/10
Containers/Layout
 Boxes
 Vertical
 Horizontal
 Combined (grid, table)
 Scrolled window
 Tabbed
widgets/notebook
 Frames
 Panes
Bernhard.Lohkamp@ki.se
7/5/10
Boxed layout
Bernhard.Lohkamp@ki.se
7/5/10
Tabbed window/Notebook
Bernhard.Lohkamp@ki.se
tabs
7/5/10
Buttons






Button
Toggle button
Check button
Spin button
Radio button
Pre-defined buttons
 Files
 Colours
 Fonts
…
Bernhard.Lohkamp@ki.se
7/5/10
Input & Entries (I)
 Menu
 Toolbar
Bernhard.Lohkamp@ki.se
7/5/10
Menus
 Submenus
 Icons
 Accelerators
Bernhard.Lohkamp@ki.se
7/5/10
Context menu
 Shown upon
event (usually
mouse click)
Bernhard.Lohkamp@ki.se
7/5/10
Toolbars
 Like menus but contain icons/buttons
 Short-cut for frequently used functions
Bernhard.Lohkamp@ki.se
7/5/10
Toolbar
Bernhard.Lohkamp@ki.se
7/5/10
Change
Style
Bernhard.Lohkamp@ki.se
7/5/10
Text
only
Bernhard.Lohkamp@ki.se
7/5/10
Text
and
Icons
Bernhard.Lohkamp@ki.se
7/5/10
Toolbar
Detouch/
Handle
Bernhard.Lohkamp@ki.se
7/5/10
detouched
Bernhard.Lohkamp@ki.se
7/5/10
Input & Entries (I)
 Combobox –
spin button
 Simple Entry:
Bernhard.Lohkamp@ki.se
7/5/10
Input & Entries (II)
 Entry:
 Auto-completion possible
 Sliders
Bernhard.Lohkamp@ki.se
7/5/10
List/Tree structures
Bernhard.Lohkamp@ki.se
7/5/10
 Can include: icons, buttons, …
Bernhard.Lohkamp@ki.se
7/5/10
 Tree-> expansion
Bernhard.Lohkamp@ki.se
7/5/10
Miscellaneous widgets
 Progress bar
 Status bar
Bernhard.Lohkamp@ki.se
7/5/10
Canvas
 Drawing area
 Canvas/cairo drawing
(e.g. PyGoocanvas)
 OpenGL drawing (e.g.
PyOpenGL, PyGtkGLExt)
 Can be interactive
Bernhard.Lohkamp@ki.se
7/5/10
Tooltips
 Pop ups with text
(upon mouse over)
 Helps to explore the
GUI without reading
help files
 Use whenever you
can (!?)
Bernhard.Lohkamp@ki.se
7/5/10
GUI design
What makes a good UI?





Simple
Intuitive
Respects the commonly accepted conventions
Visually organized
Native look
Bernhard.Lohkamp@ki.se
7/5/10
Designing UIs
 Two levels:
 Graphical: visual aspect
 Events: Functionality
 Basic blocks = widgets
 Making an application react to events = binding
Bernhard.Lohkamp@ki.se
7/5/10
General concepts
 Main loop and events
 Packing
 Showing
 How to do.
Bernhard.Lohkamp@ki.se
7/5/10
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) finishes
 Can have multiple loops (count!!)
 PyGTK:
 TKinter:
 PyQT:
Bernhard.Lohkamp@ki.se
gtk.main()
tk.mainloop()
application.exec_()
7/5/10
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)
Bernhard.Lohkamp@ki.se
7/5/10
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)
Bernhard.Lohkamp@ki.se
7/5/10
Synergy between objects and widgets
 Variables are passed automatically within class
 refer to them as self.whatever
 No need to pass variables
 Callback functions
 Easy to handle
 No need to define callbacks on the fly (lambda functions)
Bernhard.Lohkamp@ki.se
7/5/10
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)
Bernhard.Lohkamp@ki.se
7/5/10
Packing
 Homogeneous
(equal space for
everyone)
HBox(True/False, 0)
 Expand, fill
box.pack(expand=,
fill=)
Bernhard.Lohkamp@ki.se
7/5/10
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()
Bernhard.Lohkamp@ki.se
7/5/10
Simple example
 GUI command input
 Schematic in terms
of widgets
window
VBox
HBox
Label
ScrolledWindow
Entry
TextBuffer
Button
Bernhard.Lohkamp@ki.se
7/5/10
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)
Bernhard.Lohkamp@ki.se
7/5/10
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("
Bernhard.Lohkamp@ki.se
Close
")
7/5/10
Simple example
- pack it in
window
VBox
HBox
Label
ScrolledWindow
# add vbox in window
Entry
TextBuffer
Button
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)
Bernhard.Lohkamp@ki.se
7/5/10
Simple example
- pack it in
window
VBox
HBox
Label
ScrolledWindow
Entry
TextBuffer
Button
# 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)
Bernhard.Lohkamp@ki.se
7/5/10
Simple example
- show it
# show everything connected to the window
window.show_all()
# run the main loop
gtk.main()
Bernhard.Lohkamp@ki.se
7/5/10
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()
Bernhard.Lohkamp@ki.se
7/5/10
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()
Bernhard.Lohkamp@ki.se
7/5/10
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"))
Bernhard.Lohkamp@ki.se
7/5/10
Glade (GUI builders)
Inspector
Palette
Editor
Properties
Bernhard.Lohkamp@ki.se
7/5/10
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>
Bernhard.Lohkamp@ki.se
==> 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/10
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()
Bernhard.Lohkamp@ki.se
7/5/10
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)
Bernhard.Lohkamp@ki.se
7/5/10
(lib)glade
 same principle (as for gtk.Builder)
 slightly different syntax
Bernhard.Lohkamp@ki.se
7/5/10
The higher end implementations
Combining C/C++/Python/GTK
Python
Bernhard.Lohkamp@ki.se
7/5/10
Coot and Python
SWIG
Python
functions
C(++)-functions
Python
interface
Python
scripting functions
call
return value
Python functions
(objects)
Gtk+ objects
(graphics)
Bernhard.Lohkamp@ki.se
7/5/10
Main Menubar
Main Menubar
Bernhard.Lohkamp@ki.se
7/5/10
Accessing existing menus
Addition of individual
menu items
Bernhard.Lohkamp@ki.se
7/5/10
Main Toolbar
Main Toolbar
Bernhard.Lohkamp@ki.se
7/5/10
Main Toolbar
Pop-up menu
to manage
toolbuttons
Extra toolbuttons
Bernhard.Lohkamp@ki.se
7/5/10
Some hints for your own design:
Organize
Bernhard.Lohkamp@ki.se
7/5/10
Some hints for your own design:
group related items
Bernhard.Lohkamp@ki.se
7/5/10
Some hints for your own design:
keep it simple
Bernhard.Lohkamp@ki.se
7/5/10
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!!
Bernhard.Lohkamp@ki.se
7/5/10
Further information on GUI/Python/TKs

GUI






PyGTK, Glade





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
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/
Bernhard.Lohkamp@ki.se
7/5/10
Acknowledgements
http://www.biop.ox.ac.uk/coot/
or




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
Bernhard.Lohkamp@ki.se
Google: Coot
or
http://www.ysbl.ac.uk/~lohkamp/coot
7/5/10
DEMO?
Bernhard.Lohkamp@ki.se
7/5/10
Hierarchy
Bernhard.Lohkamp@ki.se
7/5/10
Bernhard.Lohkamp@ki.se
7/5/10
Download