1 / 28

Creating quick/simple QT-based GUIs in Python

Creating quick/simple QT-based GUIs in Python. Pete R. Jemian Advanced Photon Source, Argonne National Laboratory 2012 EPICS Collaboration Meeting SLAC, Menlo Park, CA 2012-04-24. svn co https:// subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo / qtprobe-demo

Download Presentation

Creating quick/simple QT-based GUIs in Python

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Creating quick/simple QT-based GUIs in Python Pete R. Jemian Advanced Photon Source, Argonne National Laboratory 2012 EPICS Collaboration Meeting SLAC, Menlo Park, CA 2012-04-24 svn co https://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo /qtprobe-demo documentation: https://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo/docs/build/html/index.html

  2. Outline • My tool set • A few basics about PyEpics • Our target application: EPICS Probe • PySide Probe, from Matt Newville, CARS • Enthought Tool Suite (ETS) Traits Probe, simple • ETS Traits Probe, more features • NOTE: all code shown in this presentation is available from subversion • svn co http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo ./qtprobe-demo EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  3. Development Tools • OS • Windows 7 • Linux: RHEL5, RHEL6, Ubuntu 10.04, 11.04, 11.10 • Mac OSX • SunOS 5.10 • Python 2.7 • EnthoughtPython Distribution 7.2-2 (http://www.enthought.com/products/epd.php) • 90+ packages including PyQt and wxPythonbackends, plus numpy, scipy, matplotlib • Traits (http://code.enthought.com/projects/traits/) • PyEpics (http://cars9.uchicago.edu/software/python/pyepics3/) • eclipse 3.7 (http://eclipse.org) • PyDev (http://pydev.org/updates) Usual disclaimers apply here: This is not an endorsement. I just use these tools. EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  4. PyEpics basicshttp://cars9.uchicago.edu/software/python/pyepics3/ • PyEpics is a Python interface for Channel Access (CA) • Provides EPICS package • fairly complete • camodule: thin layer over the low-level Channel Access library • PV module: abstraction of EPICS Process Variable as an easy-to-use Python object • Device module: create higher-level abstractions such as Motor or Scaler • Requires EPICS libca & libComlibraries, numpypackage is optional • Simple, functional approach to CA (similar to EZCA) • Examples of simple commands • epics.caget() • epics.caput() • epics.camonitor() • epics.cainfo() EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  5. Quick PyEpics demo jemian@como-ubuntu64:~/...se/qtprobe-demo$ python Enthought Python Distribution -- www.enthought.com Version: 7.2-2 (64-bit) Python 2.7.2 |EPD 7.2-2 (64-bit)| (default, Jul 3 2011, 15:17:51) [GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2 Type "packages", "demo" or "enthought" for more information. >>> import epics >>> print epics.caget('prj:datetime') 2012-04-24 08:39:37 >>> epics.caput('prj:m1.DESC', 'This is motor 1') 1 >>> EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  6. Quick PyEpicsdemo … >>> print epics.cainfo('prj:m1.DESC') == prj:m1.DESC (native_string) == value = This is motor 1 char_value = 'This is motor 1' count = 1 nelm = 1 type = string host = dhcpvisitor218180.slac.stanford.edu:5064 access = read/write status = 0 severity = 0 timestamp = 1335274922.470 (2012-04-24 08:42:02.470303) PV is internally monitored, with 0 user-defined callbacks: ============================= None >>> EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  7. Our target application: EPICS Probe • Basic Features • Displays current value of any EPICS process variable • Provides a text entry widget for use to change to a different PV • Options • Display metadata about PV • Display alarm status • Display engineering units • Change display format • Change current value of PV • Display timestamp of PV EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  8. PySide (http://www.pyside.org/) • What is PySide? • “The PySide project provides LGPL-licensed Python bindings for the Qt cross-platform application and UI framework. PySideQt bindings allow both free open source and proprietary software development and ultimately aim to support all of the platforms as Qt itself.” • Alternative to PyQt4 package • Why? • PySide is LGPL, more permissive license than PyQt4 which uses GPL • See also: http://stackoverflow.com/questions/1297660/pyside-vs-pyqt • PySide (LGPL) allows linking from closed source software • PyQt (GPL) does not, and requires separate commercial license. • Key differences from PyQt4 • http://qt-project.org/wiki/Differences_Between_PySide_and_PyQt • Different import name (PySide instead of PyQt4) • New-style signals and slots use slightly different syntax (PSEP 100) EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  9. HelloWorld using PySide EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  10. pyside_probe.py : preamble #!/usr/bin/env python ########### SVN repository information ################### # $Date: 2012-04-24 09:42:01 -0500 (Tue, 24 Apr 2012) $ # $Author: jemian $ # $Revision: 819 $ # $URL: https://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo/pyside_probe.py $ # $Id: pyside_probe.py 819 2012-04-24 14:42:01Z jemian $ ########### SVN repository information ################### # from Matt Newville, CARS, University of Chicago import epics import sys from PySide.QtGui import QWidget, QLabel, QLineEdit, QGridLayout, QApplication EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  11. pyside_probe.py : “main” if __name__ == '__main__': app = QApplication(sys.argv) probe = PVProbe() probe.show() sys.exit(app.exec_()) EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  12. pyside_probe.py : PvProbe class and initialization A signal is emitted when a particular event occurs. A slot can be any Python callable. A slot is called when a signal connected to it is emitted. class PVProbe(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) name_label = QLabel("PV Name:") self.pvname = QLineEdit() value_label = QLabel("PV Value:") self.value = QLabel(" "*4) self.pvname.returnPressed.connect(self.onPVNameReturn) self.pv = None grid = QGridLayout() grid.addWidget(name_label, 0, 0) grid.addWidget(self.pvname, 0, 1) grid.addWidget(value_label, 1, 0) grid.addWidget(self.value, 1, 1) self.setLayout(grid) self.setWindowTitle("PySide PV Probe:") EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  13. pyside_probe.py : PvProbe class action handlers defonPVNameReturn(self): if self.pv is not None: self.pv.remove_callback() self.pv.disconnect() self.pv = epics.PV(self.pvname.text(), callback=self.onPVChange) defonPVChange(self, pvname=None, char_value=None, **kws): self.value.setText(char_value) EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  14. pyside_probe.py : run it jemian@como-ubuntu64:~/...se/qtprobe-demo$ ./pyside_probe.py & [1] 10323 EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  15. PyEpics: camonitor()callback handlerhttp://cars9.uchicago.edu/software/python/pyepics3/pv.html#user-supplied-callback-functions defca_callback(self, **kw): ''' process an EPICS CA monitor callback event, event information willbe in kwdictionary ''' logger = logging.getLogger(__name__) logger.debug( "callback: %s = %s" % (kw['pvname'], kw['char_value']) ) • Callback functions will be called with several keyword arguments. • Prepare to handle them as a dictionary: **kw • See the online docs for other variations and the complete list of keywords EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  16. Traits basicshttp://code.enthought.com/projects/traits • “Python does not require the data type of variables to be declared. As any experienced Python programmer knows, this flexibility has both good and bad points. The Traits package was developed to address some of the problems caused by not having declared variable types, in those cases where problems might arise.” • Huh? • Provides strongly-typed objects for Python • The TraitsUI package is a set of user interface tools designed to complement Traits • Used in ETC plotting package: Chaco EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  17. Traits example: simpleton.py from enthought.traits.api import HasTraits, String, Int, Float class Simpleton(HasTraits): desc = String quantity = Int alpha = Float beta = Float gamma = Float if __name__ == '__main__': example = Simpleton() result = example.configure_traits() print result print example.desc, example.quantity print example.alpha, example.beta, example.gamma EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  18. Starting Traits with Qt4 backend • Traits supports either wxPython (default) or Qt4 backends • Here’s how to enforce use of the Qt4 backend • MUST put this code before any other Traits imports! from traits.etsconfig.api import ETSConfig ETSConfig.toolkit= 'qt4' EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  19. traits_probe.py : main import argparse if __name__ == '__main__': #pv = '' #if len(sys.argv) == 2: # pv = sys.argv[1] parser = argparse.ArgumentParser( description="traits_probe") parser.add_argument( 'pv', action='store', nargs='?', help="EPICS PV name", default="EpicsDemo1“) results = parser.parse_args() probe = Probe(name=results.pv) probe.configure_traits() EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  20. traits_probe.py : Probe class class Probe( HasTraits ): name = Str value = Str _chid = Instance( epics.PV, value = None ) defdo_callback(self, value=None, **kwds): "simple monitor callback" self.value = str(value) traits_view = View( Item('name'), Readonly('value'), resizable=True, width = 250, title='Traits-based EPICS Probe', key_bindings = key_bindings, handler = CodeHandler() ) EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  21. traits_probe.py : CodeHandler class # TraitsUI Handler class for bound methods class CodeHandler ( Handler ): def connect ( self, info ): if len(info.object.name) > 0: try: if info.object._chid is not None: info.object._chid.cancel_callback() info.object._chid.disconnect() except: pass info.object._chid = epics.PV( str(info.object.name), callback=info.object.do_callback ) EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  22. traits_probe.py : preamble import argparse import epics import sys #@UnusedImport from traits.etsconfig.api import ETSConfig ETSConfig.toolkit= 'qt4' from traits.api import * #@UnusedWildImport from traitsui.api import * #@UnusedWildImport from traitsui.key_bindings import KeyBinding, KeyBindings key_bindings = KeyBindings( KeyBinding( binding1 = 'Enter', method_name = 'connect‘, description = 'Connect to new PV',), KeyBinding( binding1 = 'Return',method_name = 'connect‘, description = 'Connect to new PV', ), ) EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  23. traits_probe.py : example EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  24. traits_probe_more.py : structure • Four classes: ActionHandler, SimpleEpicsTraitsTest, ShowInfo, ShowAbout EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  25. traits_probe_more.py : implementing “info” my_button_actions = [. . ., Action(name="Info", action="show_info", desc="show PV info"), . . . ] class ActionHandler(Handler): . . . defshow_info(self, uinfo): '''information about the EPICS PV''' self.define_gui(uinfo) if self._watching and self._ch is not None: self._gui.SetStatus('showing PV info') ShowInfo(text=self._ch.info).edit_traits() else: self._gui.SetStatus('must Watch a PV first') class ShowInfo( HasTraits ): '''dead simple PV Info box''' text = Str view = View( UReadonly('text'), title='PV info ...' ) view = View(. . ., handler = ActionHandler(), buttons = my_button_actions, . . .,) EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  26. traits_probe_more.py : run it EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  27. Take-home Remarks: • Traits • Works really well for simple things, good choice for simple GUIs • Easy to add new GUI elements • Program execution flow is not obvious • Some unresolved threading challenges encountered on Win7 and RHEL • Supports both wxPython and Qt4 backends • PySide • Regular Qt4 implementation • Easier to debug • Best choice for GUI with any complexity • LGPL license allows greater use (than PyQt4) • Eclipse + PyDev is a great combination for a developer • Use of EPD allows to define minimum configuration for users EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

  28. Thank you for your attention! EPICS 2012 @ SLAC: Jemian: Creating quick/simple QT-based GUIs in Python -- http://subversion.xor.aps.anl.gov/bcdaext/qtprobe-demo

More Related