diff -r 73bd2fe81005 -r 8becd52c2171 HP3562A/q3562A.py
--- /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("Unable to initialize GPIB connection.
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()