gui design with python – examples from crystallography bernhard lohkamp karolinska institute...
Post on 20-Dec-2015
228 Views
Preview:
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