pygpibtoolkit/plotter/qgpib_plotter.py

changeset 98
4cbd3d410230
parent 91
f2a8f688dbc0
child 104
916c255b3079
equal deleted inserted replaced
97:3f123b64d367 98:4cbd3d410230
17 import os 17 import os
18 import sys 18 import sys
19 import time 19 import time
20 20
21 from PyQt5 import QtWidgets, QtGui, QtCore, QtPrintSupport, uic 21 from PyQt5 import QtWidgets, QtGui, QtCore, QtPrintSupport, uic
22 from PyQt5.QtCore import Qt 22 from PyQt5.QtCore import Qt, pyqtSignal
23 23
24 from pygpibtoolkit.plotter.hpgl_qt import QHPGLPlotterWidget 24 from pygpibtoolkit.plotter.hpgl_qt import QHPGLPlotterWidget
25 from pygpibtoolkit.plotter.gpib_plotter import GPIBplotter
25 26
26 from pygpibtoolkit.qt5.qpreferences import IntItem, UnicodeItem, ColorItem 27 from pygpibtoolkit.qt5.qpreferences import IntItem, UnicodeItem, ColorItem
27 from pygpibtoolkit.qt5.qpreferences import BoolItem 28 from pygpibtoolkit.qt5.qpreferences import BoolItem
28 from pygpibtoolkit.qt5.qpreferences import PointItem, SizeItem, ByteArrayItem 29 from pygpibtoolkit.qt5.qpreferences import PointItem, SizeItem, ByteArrayItem
29 from pygpibtoolkit.qt5.qpreferences import AbstractPreferences 30 from pygpibtoolkit.qt5.qpreferences import AbstractPreferences
38 try: 39 try:
39 form_class, base_class = uic.loadUiType( 40 form_class, base_class = uic.loadUiType(
40 os.path.join(HERE, "qhpgl_plotter.ui"), 41 os.path.join(HERE, "qhpgl_plotter.ui"),
41 from_imports=True, import_from='pygpibtoolkit.plotter',) 42 from_imports=True, import_from='pygpibtoolkit.plotter',)
42 except Exception as e: 43 except Exception as e:
43 print(e) 44 from pygpibtoolkit.plotter.qhpgl_plotter_ui import (
44 from pygpibtoolkit.plotter.qhpgl_plotter_ui import Ui_MainWindow as form_class 45 Ui_MainWindow as form_class)
45 46
46 47
47 if "-m" in sys.argv:
48 from pygpibtoolkit.plotter.gpib_plotter_mockup import GPIBplotter
49 else:
50 from pygpibtoolkit.plotter.gpib_plotter import GPIBplotter
51 48
52 49
53 class Preferences(AbstractPreferences): 50 class Preferences(AbstractPreferences):
54 ORGANISATION = "PyGPIBToolkit" 51 ORGANISATION = "PyGPIBToolkit"
55 APPLICATION = "qgpib_plotter" 52 APPLICATION = "qgpib_plotter"
95 group="Colors") 92 group="Colors")
96 93
97 autodisplay = BoolItem( 94 autodisplay = BoolItem(
98 default=True, 95 default=True,
99 name="Auto display", 96 name="Auto display",
100 description="Automatically display a new plot as soon as it is received", 97 description=(
98 "Automatically display a new plot as soon as it is received"),
101 group="Misc") 99 group="Misc")
102 100
103 101
104 class QtHPGLPlotter(QtWidgets.QMainWindow, form_class): 102 class QtHPGLPlotter(QtWidgets.QMainWindow, form_class):
105 def __init__(self, parent=None): 103 def __init__(self, parent=None):
149 self.captureButton.toggled.connect(self.captureToggled) 147 self.captureButton.toggled.connect(self.captureToggled)
150 148
151 self._plots_list = QtCore.QStringListModel() 149 self._plots_list = QtCore.QStringListModel()
152 self.plotsView.setModel(self._plots_list) 150 self.plotsView.setModel(self._plots_list)
153 self.plotsView.activated.connect(self.currentPlotChanged) 151 self.plotsView.activated.connect(self.currentPlotChanged)
154 self.plotsView.selectionModel().currentChanged.connect(self.currentPlotChanged) 152 self.plotsView.selectionModel().currentChanged.connect(
153 self.currentPlotChanged)
155 self.setReceivingLed() 154 self.setReceivingLed()
156 155
157 def currentPlotChanged(self, index, old_index=None): 156 def currentPlotChanged(self, index, old_index=None):
158 if index.isValid(): 157 if index.isValid():
159 value = self.plotsView.model().data(index, Qt.DisplayRole) 158 value = self.plotsView.model().data(index, Qt.DisplayRole)
168 167
169 def quitTriggered(self, checked=False): 168 def quitTriggered(self, checked=False):
170 self.close() 169 self.close()
171 170
172 def closeEvent(self, event): 171 def closeEvent(self, event):
172 # if self.promptForSave():
173 if 1: 173 if 1:
174 #if self.promptForSave():
175 self._prefs._pos = self.pos() 174 self._prefs._pos = self.pos()
176 self._prefs._size = self.size() 175 self._prefs._size = self.size()
177 self._prefs._appState = self.saveState() 176 self._prefs._appState = self.saveState()
178 event.accept() 177 event.accept()
179 else: 178 else:
191 self.plotsView.setCurrentIndex(self.plotsView.model().index(0, 0)) 190 self.plotsView.setCurrentIndex(self.plotsView.model().index(0, 0))
192 191
193 def openFiles(self, filenames): 192 def openFiles(self, filenames):
194 ok = False 193 ok = False
195 for filename in filenames: 194 for filename in filenames:
196 print('FNAE=', filename)
197 if os.path.exists(filename): 195 if os.path.exists(filename):
198 data = open(filename).read() 196 data = open(filename).read()
199 name = os.path.basename(filename) 197 name = os.path.basename(filename)
200 name = os.path.splitext(name)[0] 198 name = os.path.splitext(name)[0]
201 lst = self.plotsView.model().stringList() 199 lst = self.plotsView.model().stringList()
258 open(filename, 'w').write(self._plots[value]) 256 open(filename, 'w').write(self._plots[value])
259 257
260 def initializeGPIB(self): 258 def initializeGPIB(self):
261 self._online = False 259 self._online = False
262 try: 260 try:
263 self.gpib_plotter = QGPIBplotter(device=self._prefs.device, 261 self.gpib_plotter = GPIBplotter(
264 address=self._prefs.address, 262 device=self._prefs.device,
265 ) 263 address=self._prefs.address,
264 )
266 self.captureThread = GPIBReceiver(self.gpib_plotter) 265 self.captureThread = GPIBReceiver(self.gpib_plotter)
267 self.captureThread.plotReceived.connect(self.plotReceived) 266 self.captureThread.plotReceived.connect(self.plotReceived)
268 self.captureThread.plotStarted.connect(self.plotStarted) 267 self.captureThread.plotStarted.connect(self.plotStarted)
269 self.captureThread.start() 268 self.captureThread.start()
270 except Exception as e: 269 except Exception as e:
276 if state: 275 if state:
277 if self.gpib_plotter is None: 276 if self.gpib_plotter is None:
278 self.initializeGPIB() 277 self.initializeGPIB()
279 if self.gpib_plotter is None: 278 if self.gpib_plotter is None:
280 QtWidgets.QMessageBox.critical( 279 QtWidgets.QMessageBox.critical(
281 self, self.tr("GPIB error"), 280 self, "GPIB error",
282 self.tr("<b>Unable to initialize GPIB connection</b>." 281 "<b>Unable to initialize GPIB connection</b>."
283 "<br>Please check your GPIB dongle and settings.")) 282 "<br>Please check your GPIB dongle and settings.")
284 self._online = False 283 self._online = False
285 self.setCaptureLed() 284 self.setCaptureLed()
286 return 285 return
287 self._online = True 286 self._online = True
288 self.captureThread.startCapture() 287 self.captureThread.startCapture()
306 else: 305 else:
307 icn = QtGui.QIcon(':/icons/led_red_off.svg') 306 icn = QtGui.QIcon(':/icons/led_red_off.svg')
308 self.receivingButton.setIcon(icn) 307 self.receivingButton.setIcon(icn)
309 308
310 309
311 class QGPIBplotter(GPIBplotter):
312 def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1,
313 address=5):
314 super().__init__(device, baudrate, timeout, address)
315 self.emitter = None
316
317 def plotStarted(self):
318 if self.emitter:
319 self.emitter.emit(SIGNAL('plotStarted()'))
320 # self.emitter.msleep(1)
321
322 310
323 class GPIBReceiver(QtCore.QThread): 311 class GPIBReceiver(QtCore.QThread):
312 plotStarted = pyqtSignal()
313 plotReceived = pyqtSignal(int)
314
324 def __init__(self, cnx, parent=None): 315 def __init__(self, cnx, parent=None):
325 super().__init__(parent) 316 super().__init__(parent)
326 self.gpibplotter = cnx 317 self.gpibplotter = cnx
327 self.gpibplotter.emitter = self 318 self.gpibplotter.plot_started_cb = self.plotStarted.emit
328 319
329 self._cancelmutex = QtCore.QMutex()
330 self._cancel = False 320 self._cancel = False
331 # self._nreceived = 0 321 # self._nreceived = 0
332 self._plotsmutex = QtCore.QMutex() 322 self._plotsmutex = QtCore.QMutex()
333 self._plots = [] 323 self._plots = []
334 self._startstopmutex = QtCore.QMutex()
335 self._startstop = QtCore.QWaitCondition()
336 self._capturing = False 324 self._capturing = False
337 325
338 def cancel(self): 326 def cancel(self):
339 self._cancelmutex.lock()
340 self._cancel = True 327 self._cancel = True
341 self._cancelmutex.unlock()
342 328
343 def startCapture(self): 329 def startCapture(self):
344 self._startstop.wakeOne() 330 self._capturing = True
345 331
346 def stopCapture(self): 332 def stopCapture(self):
347 self._startstopmutex.lock()
348 self._capturing = False 333 self._capturing = False
349 self._startstopmutex.unlock()
350 334
351 def run(self): 335 def run(self):
352 while 1: 336 while not self._cancel:
353 self._cancelmutex.lock()
354 if self._cancel:
355 return
356 self._cancelmutex.unlock()
357 self._startstopmutex.lock()
358 if not self._capturing: 337 if not self._capturing:
359 self._startstop.wait(self._startstopmutex) 338 self.msleep(100)
360 self._capturing = True 339 continue
361 self._startstopmutex.unlock() 340
362 plot = self.gpibplotter.load_plot(wait_timeout=0.1) 341 plot = self.gpibplotter.load_plot(wait_timeout=0.1)
363 timestamp = time.time() 342 timestamp = time.time()
364 if plot: 343 if plot:
365 self._plotsmutex.lock() 344 self._plotsmutex.lock()
366 self._plots.append((plot, timestamp)) 345 self._plots.append((plot, timestamp))
367 n = len(self._plots) 346 n = len(self._plots)
368 self._plotsmutex.unlock() 347 self._plotsmutex.unlock()
369 self.emit(SIGNAL('plotReceived(int)'), n-1) 348
349 self.plotReceived.emit(n - 1)
370 self.msleep(10) 350 self.msleep(10)
371 351
372 def getPlot(self, num): 352 def getPlot(self, num):
373 self._plotsmutex.lock() 353 self._plotsmutex.lock()
374 try: 354 try:
376 finally: 356 finally:
377 self._plotsmutex.unlock() 357 self._plotsmutex.unlock()
378 358
379 359
380 def main(): 360 def main():
361 global GPIBplotter
362
381 import optparse 363 import optparse
382 opt = optparse.OptionParser( 364 opt = optparse.OptionParser(
383 'A simple PyQt4 HP7470A GPIB plotter emulator for USB-GPIB bundle ' 365 'A simple PyQt4 HP7470A GPIB plotter emulator for USB-GPIB bundle '
384 '(Prologix)') 366 '(Prologix)')
385 opt.add_option('-m', '--mockup', default=False, 367 opt.add_option('-m', '--mockup', default=False,
391 action="store_true", 373 action="store_true",
392 dest="verbose", 374 dest="verbose",
393 help="Verbose mode",) 375 help="Verbose mode",)
394 376
395 options, argv = opt.parse_args(sys.argv) 377 options, argv = opt.parse_args(sys.argv)
378 if options.mockup:
379 from pygpibtoolkit.plotter.gpib_plotter_mockup import GPIBplotter
396 380
397 a = QtWidgets.QApplication(argv) 381 a = QtWidgets.QApplication(argv)
398 w = QtHPGLPlotter() 382 w = QtHPGLPlotter()
399 files = [f for f in argv[1:] if os.path.isfile(f)] 383 files = [f for f in argv[1:] if os.path.isfile(f)]
400 files.sort(key=str_num_key) 384 files.sort(key=str_num_key)

mercurial