HP3562A/q3562A.py

changeset 39
8becd52c2171
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HP3562A/q3562A.py	Mon Feb 04 19:49:48 2008 +0100
@@ -0,0 +1,346 @@
+#
+
+import os, sys
+import time
+import glob
+
+from PyQt4 import QtGui, QtCore, uic
+from PyQt4.QtCore import SIGNAL, Qt
+
+if "-m" in sys.argv:
+    from dump_datablock_mockup import HP3562dumper
+else:
+    from dump_datablock import HP3562dumper
+import q3562A_rc
+
+ldir = os.path.abspath(os.path.dirname(__file__))
+sys.path.append(ldir)
+form_class, base_class = uic.loadUiType(os.path.join(ldir, "q3562A.ui"))
+
+from qpreferences import BaseItem, IntItem, UnicodeItem, ColorItem
+from qpreferences import PointItem, SizeItem, ByteArrayItem
+from qpreferences import AbstractPreferences
+from qpreferenceseditor import PreferencesEditor
+
+from tools import str_num_cmp
+
+class Preferences(AbstractPreferences):
+    ORGANISATION="Logilab"
+    APPLICATION="qgpib_plotter"
+
+    _pos = PointItem()
+    _size = SizeItem()
+    _appState = ByteArrayItem()
+
+    device = UnicodeItem(default='/dev/ttyUSB0',
+                         name=u'device',
+                         description=u'GPIB device',
+                         group="GPIB settings")
+    address = IntItem(default=5, min=0, max=16,
+                      name=u'GPIB address',
+                      group="GPIB settings")
+    
+    background = ColorItem(default=QtGui.QColor("white"),
+                           name="Background",
+                           group="Colors")
+    color0 = ColorItem(default=QtGui.QColor("black"),
+                       name="Pen #0",
+                       group="Colors")
+    color1 = ColorItem(default=QtGui.QColor("green"),
+                       name="Pen #1",
+                       group="Colors")
+    color2 = ColorItem(default=QtGui.QColor("red"),
+                       name="Pen #2",
+                       group="Colors")
+    color3 = ColorItem(default=QtGui.QColor("blue"),
+                       name="Pen #3",
+                       group="Colors")
+    color4 = ColorItem(default=QtGui.QColor("yellow"),
+                       name="Pen #4",
+                       group="Colors")
+    color5 = ColorItem(default=QtGui.QColor("cyan"),
+                       name="Pen #5",
+                       group="Colors")
+    color6 = ColorItem(default=QtGui.QColor("magenta"),
+                       name="Pen #6",
+                       group="Colors")
+    color7 = ColorItem(default=QtGui.QColor("darkred"),
+                       name="Pen #7",
+                       group="Colors")
+    
+class QtHPGLPlotter(QtGui.QMainWindow, form_class):
+    def __init__(self, parent=None):
+        QtGui.QMainWindow.__init__(self, parent)
+        self._plots = {}        
+        self._prefs = Preferences()
+        self.setupUi()
+        self.initializeGPIB()
+        if self._prefs._pos:
+            self.move(self._prefs._pos)
+        if self._prefs._size:
+            self.resize(self._prefs._size)
+        if self._prefs._appState:
+            self.restoreState(self._prefs._appState)
+        self.readPreferences()
+
+    def readPreferences(self):
+        bg = self._prefs.background
+        if bg and bg.isValid():
+            self.plotterWidget.qview.setBackgroundBrush(QtGui.QBrush(bg))
+        pen_colors = [self._prefs["color%d"%i] for i in range(8)]
+        self.plotterWidget.pen_colors = pen_colors
+        
+    def replotCurrent(self):
+        self.currentPlotChanged(self.plotsView.currentIndex())
+        
+    def setupUi(self):
+        form_class.setupUi(self, self) # call qtdesigner generated form creation        
+        # actions defined in designer
+        self.connect(self.actionPreferences, SIGNAL('triggered(bool)'),
+                     self.preferencesTriggered)
+        self.connect(self.actionQuit, SIGNAL('triggered(bool)'),
+                     self.quitTriggered)
+        self.actionQuit.setShortcut(QtGui.QKeySequence(u'Ctrl+Q'))
+        self.connect(self.actionOpen, SIGNAL('triggered(bool)'),
+                     self.openTriggered)
+        self.actionOpen.setShortcut(QtGui.QKeySequence(u'Ctrl+O'))
+        self.connect(self.actionSave, SIGNAL('triggered(bool)'),
+                     self.saveTriggered)
+        self.actionSave.setShortcut(QtGui.QKeySequence(u'Ctrl+S'))
+        self.connect(self.actionSaveAs, SIGNAL('triggered(bool)'),
+                     self.saveAsTriggered)
+
+        self.plotterWidget = QHPGLPlotterWidget(self)
+        self.setCentralWidget(self.plotterWidget)
+
+        self.connect(self.captureButton, SIGNAL("toggled(bool)"),
+                     self.captureToggled)
+
+        self._plots_list = QtGui.QStringListModel()
+        self.plotsView.setModel(self._plots_list)
+        self.connect(self.plotsView, SIGNAL('activated(const QModelIndex&)'),
+                     self.currentPlotChanged)
+        self.connect(self.plotsView.selectionModel(),
+                     SIGNAL('currentChanged(const QModelIndex&, const QModelIndex&)'),
+                     self.currentPlotChanged)
+
+    def currentPlotChanged(self, index, old_index=None):
+        if index.isValid():
+            value = unicode(self.plotsView.model().data(index, Qt.DisplayRole).toString())
+            
+            self.plotterWidget.clear()
+            self.plotterWidget.parse(self._plots[value])
+            
+    def preferencesTriggered(self, checked=False):
+        PreferencesEditor(self._prefs, self).exec_()
+        self.readPreferences()
+        self.replotCurrent()
+
+    def quitTriggered(self, checked=False):
+        self.close()
+
+    def closeEvent(self, event):
+        if 1:
+        #if self.promptForSave():
+            self._prefs._pos = self.pos()
+            self._prefs._size = self.size()
+            self._prefs._appState = self.saveState()
+            event.accept()
+        else:
+            event.ignore()
+        
+    def openTriggered(self, checked=False):
+        filenames = QtGui.QFileDialog.getOpenFileNames(self, "Open a HPGL file to display", '.', 'HPGL files (*.plt)\nAll files (*)')
+        self.openFiles(filenames)
+        self.displayFirst()
+        
+    def displayFirst(self):
+        if not self.plotsView.currentIndex().isValid():
+            self.plotsView.setCurrentIndex(self.plotsView.model().index(0, 0))
+        
+    def openFiles(self, filenames):
+        ok = False
+        for filename in filenames:
+            filename = str(filename)
+            if os.path.exists(filename):
+                data = open(filename).read()
+                name = os.path.basename(filename)
+                name = os.path.splitext(name)[0]
+                lst = self.plotsView.model().stringList()
+                lst.append(name)            
+                self._plots[name] = data
+                self.plotsView.model().setStringList(lst)
+                ok = True
+        return ok
+        
+    def plotReceived(self, num):
+        self._receiving = False
+        self.setReceivingLed()
+        plot, timestamp = self.captureThread.getPlot(num)
+        name = "plot_%s"%(num)
+        lst = self.plotsView.model().stringList()
+        lst.append(name)            
+        self._plots[name] = plot
+        self.plotsView.model().setStringList(lst)
+
+    def plotStarted(self):
+        self._receiving = True
+        self.setReceivingLed()
+        
+    def saveTriggered(self, checked=False):
+        print "save"
+        
+    def saveAsTriggered(self, checked=False):
+        index = self.plotsView.selectionModel().currentIndex()
+        if index.isValid():
+            filename = QtGui.QFileDialog.getSaveFileName(self, "Selecte a file name to save HPGL file", '.', 'HPGL files (*.plt)\nAll files (*)')
+            n = index.row()
+            value = unicode(self.plotsView.model().data(index, Qt.DisplayRole).toString())
+            open(filename, 'w').write(self._plots[value])
+            
+        
+    def initializeGPIB(self):
+        self._online = False
+        try:
+            self.gpib_plotter = QGPIBplotter(device=self._prefs.device,
+                                            address=self._prefs.address,
+                                            )
+            self.captureThread = GPIBReceiver(self.gpib_plotter)
+            self.connect(self.captureThread, SIGNAL('plotReceived(int)'),
+                         self.plotReceived)
+            self.connect(self.captureThread, SIGNAL('plotStarted()'),
+                         self.plotStarted)
+            self.captureThread.start()
+        except Exception, e:
+            #print e
+            self.gpib_plotter = None
+        self.setCaptureLed()
+
+    def captureToggled(self, state):
+        if state:
+            if self.gpib_plotter is None:
+                self.initializeGPIB()
+                if self.gpib_plotter is None:
+                    QtGui.QMessageBox.critical(self, self.tr("GPIB error"),
+                                               self.tr("<b>Unable to initialize GPIB connection</b>.<br>Please check your GPIB dongle and settings."))
+                    self._online = False
+                    self.setCaptureLed()
+                    return
+            self._online = True
+            self.captureThread.startCapture()
+        else:
+            if self.captureThread:
+                self.captureThread.stopCapture()
+            self._online = False
+        self.setCaptureLed()
+        
+    def setCaptureLed(self):
+        if self._online:
+            icn = QtGui.QIcon(':/icons/led_green.svg')
+        else:
+            icn = QtGui.QIcon(':/icons/led_green_off.svg')
+        self.captureButton.setIcon(icn)
+        self.captureButton.setChecked(self._online)
+
+    def setReceivingLed(self):
+        if self._receiving:
+            icn = QtGui.QIcon(':/icons/led_red.svg')
+        else:
+            icn = QtGui.QIcon(':/icons/led_red_off.svg')
+        self.receivingButton.setIcon(icn)
+
+class QGPIBplotter(GPIBplotter):
+    def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1,
+                 address=5):
+        GPIBplotter.__init__(self, device, baudrate, timeout, address)        
+        self.emitter = None
+
+    def plotStarted(self):
+        if self.emitter:
+            self.emitter.emit(SIGNAL('plotStarted()'))
+            #self.emitter.msleep(1)
+        
+class GPIBReceiver(QtCore.QThread):
+    def __init__(self, cnx):
+        QtCore.QThread.__init__(self)
+        self.gpibplotter = cnx
+        self.gpibplotter.emitter = self
+        
+        self._cancelmutex = QtCore.QMutex()
+        self._cancel = False
+        #self._nreceived = 0
+        self._plotsmutex = QtCore.QMutex()
+        self._plots = []
+        self._startstopmutex = QtCore.QMutex()
+        self._startstop = QtCore.QWaitCondition()
+        self._capturing = False
+        
+    def cancel(self):
+        self._cancelmutex.lock()
+        self._cancel = True
+        self._cancelmutex.unlock()
+
+    def startCapture(self):
+        self._startstop.wakeOne()
+
+    def stopCapture(self):
+        self._startstopmutex.lock()
+        self._capturing = False
+        self._startstopmutex.unlock()
+
+    def run(self):
+        while 1:
+            self._cancelmutex.lock()
+            if self._cancel:
+                return
+            self._cancelmutex.unlock()
+            self._startstopmutex.lock()
+            if not self._capturing:
+                self._startstop.wait(self._startstopmutex)
+                self._capturing = True
+            self._startstopmutex.unlock()
+        
+            plot = self.gpibplotter.load_plot(wait_timeout=0.1)
+            timestamp = time.time()
+            if plot:
+                self._plotsmutex.lock()
+                self._plots.append((plot, timestamp))
+                n = len(self._plots)
+                self._plotsmutex.unlock()
+                self.emit(SIGNAL('plotReceived(int)'), n-1)
+            self.msleep(10)
+            
+    def getPlot(self, num):
+        self._plotsmutex.lock()
+        try:
+            return self._plots[num]
+        finally:
+            self._plotsmutex.unlock()
+
+def main():
+    import optparse
+    opt = optparse.OptionParser('A simple PyQt4 HP7470A GPIB plotter emulator for USB-GPIB bundle (ProLogix)')
+    opt.add_option('-m', '--mockup', default=False,
+                   action="store_true",
+                   dest='mockup',
+                   help='Use a pseudo GPIB connection (for test purpose)',
+                   )
+    opt.add_option('-v', '--verbose', default=False,
+                   action="store_true",
+                   dest="verbose",
+                   help="Verbose mode",)
+    
+    options, argv = opt.parse_args(sys.argv)
+
+    a = QtGui.QApplication(argv)
+    w = QtHPGLPlotter()
+    files = [f for f in argv[1:] if os.path.isfile(f)]
+    files.sort(cmp=str_num_cmp)
+    if w.openFiles(files):    
+        w.displayFirst()
+
+    w.show()
+    a.exec_()
+        
+if __name__ == '__main__':
+    main()

mercurial