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" |
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) |
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: |