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()