## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
##
+import acquisition
import datamodel
import multiplotwidget
import os.path
import qtcompat
-import samplingthread
import textwrap
import time
import util
def __init__(self, context, drivers):
super(self.__class__, self).__init__()
+ # Used to coordinate the stopping of the acquisition and
+ # the closing of the window.
+ self._closing = False
+
self.context = context
+ self.drivers = drivers
self.delegate = datamodel.MultimeterDelegate(self, self.font())
self.model = datamodel.MeasurementDataModel(self)
self.setup_ui()
- self.thread = samplingthread.SamplingThread(self.context, drivers)
- self.thread.measured.connect(self.model.update)
- self.thread.error.connect(self.error)
- self.thread.start()
+ QtCore.QTimer.singleShot(0, self._start_acquisition)
+
+ def _start_acquisition(self):
+ self.acquisition = acquisition.Acquisition(self.context)
+ self.acquisition.measured.connect(self.model.update)
+ self.acquisition.stopped.connect(self._stopped)
+
+ try:
+ for (ds, cs) in self.drivers:
+ self.acquisition.add_device(ds, cs)
+ except Exception as e:
+ QtGui.QMessageBox.critical(self, 'Error', str(e))
+ self.close()
+ return
+
+ self.acquisition.start()
def setup_ui(self):
self.setWindowTitle('sigrok-meter')
self.listView.setMinimumSize(self.delegate.sizeHint())
self.plotwidget = multiplotwidget.MultiPlotWidget(self)
+ self.plotwidget.plotHidden.connect(self._on_plotHidden)
# Maps from 'unit' to the corresponding plot.
self._plots = {}
self.startTimer(MainWindow.UPDATEINTERVAL)
+ def stop(self):
+ self.acquisition.stop()
+ print(self.acquisition.is_running())
+
def _getPlot(self, unit):
'''Looks up or creates a new plot for 'unit'.'''
def timerEvent(self, event):
'''Periodically updates all graphs.'''
- for row in range(self.model.rowCount()):
- idx = self.model.index(row, 0)
- deviceID = self.model.data(idx, datamodel.MeasurementDataModel.idRole)
- sampledict = self.model.data(idx, datamodel.MeasurementDataModel.samplesRole)
- color = self.model.data(idx, datamodel.MeasurementDataModel.colorRole)
- for unit in sampledict:
- self._updatePlot(deviceID, unit, sampledict[unit], color)
-
- def _updatePlot(self, deviceID, unit, samples, color):
- '''Updates the curve of device 'deviceID' and 'unit' with 'samples',
- changes the color of the curve to 'color'.'''
-
- plot = self._getPlot(unit)
- curve = self._getCurve(plot, deviceID)
- curve.setPen(pyqtgraph.mkPen(color=color, width=1))
+ self._updatePlots()
- now = time.time()
+ def _updatePlots(self):
+ '''Updates all plots.'''
- # remove old samples
- l = now - MainWindow.BACKLOG
- while samples and samples[0][0] < l:
- samples.pop(0)
+ # loop over all devices and channels
+ for row in range(self.model.rowCount()):
+ idx = self.model.index(row, 0)
+ deviceID = self.model.data(idx,
+ datamodel.MeasurementDataModel.idRole)
+ deviceID = tuple(deviceID) # PySide returns a list.
+ traces = self.model.data(idx,
+ datamodel.MeasurementDataModel.tracesRole)
+
+ for unit, trace in traces.items():
+ now = time.time()
+
+ # remove old samples
+ l = now - MainWindow.BACKLOG
+ while trace.samples and trace.samples[0][0] < l:
+ trace.samples.pop(0)
+
+ plot = self._getPlot(unit)
+ if not plot.visible:
+ if trace.new:
+ self.plotwidget.showPlot(plot)
+
+ if plot.visible:
+ xdata = [s[0] - now for s in trace.samples]
+ ydata = [s[1] for s in trace.samples]
+
+ color = self.model.data(idx,
+ datamodel.MeasurementDataModel.colorRole)
+
+ curve = self._getCurve(plot, deviceID)
+ curve.setPen(pyqtgraph.mkPen(color=color))
+ curve.setData(xdata, ydata)
+
+ @QtCore.Slot(multiplotwidget.Plot)
+ def _on_plotHidden(self, plot):
+ plotunit = [u for u, p in self._plots.items() if p == plot][0]
+
+ # Mark all traces of all devices/channels with the same unit as the
+ # plot as "old" ('trace.new = False'). As soon as a new sample arrives
+ # on one trace, the plot will be shown again
+ for row in range(self.model.rowCount()):
+ idx = self.model.index(row, 0)
+ traces = self.model.data(idx, datamodel.MeasurementDataModel.tracesRole)
- xdata = [s[0] - now for s in samples]
- ydata = [s[1] for s in samples]
+ for traceunit, trace in traces.items():
+ if traceunit == plotunit:
+ trace.new = False
- curve.setData(xdata, ydata)
+ @QtCore.Slot()
+ def _stopped(self):
+ if self._closing:
+ self.close()
def closeEvent(self, event):
- self.thread.stop()
- event.accept()
+ if self.acquisition.is_running():
+ self._closing = True
+ self.acquisition.stop()
+ event.ignore()
+ else:
+ event.accept()
@QtCore.Slot()
def show_about(self):
QtGui.QMessageBox.about(self, 'About sigrok-meter', text)
- @QtCore.Slot(str)
- def error(self, msg):
- '''Error handler for the sampling thread.'''
- QtGui.QMessageBox.critical(self, 'Error', msg)
- self.close()
-
@QtCore.Slot(object, int, int)
def modelRowsInserted(self, parent, start, end):
'''Resize the list view to the size of the content.'''