]> sigrok.org Git - sigrok-meter.git/blobdiff - sigrok-meter
Don't pass the packet.payload between threads.
[sigrok-meter.git] / sigrok-meter
index ce7dbf36a7d6ab276a17487ac5725103e4b6f7b2..6f83443a5368df92dc4b4b7a6d20b8d2546edcc3 100755 (executable)
@@ -123,22 +123,18 @@ class SamplingThread(QtCore.QObject):
         '''Helper class that does the actual work in another thread.'''
 
         '''Signal emitted when new data arrived.'''
-        measured = QtCore.Signal(object, object)
+        measured = QtCore.Signal(object, object, object)
 
         '''Signal emmited in case of an error.'''
         error = QtCore.Signal(str)
 
-        def __init__(self, drivers, loglevel):
+        def __init__(self, context, drivers):
             super(self.__class__, self).__init__()
 
-            self.sampling = False
+            self.context = context
             self.drivers = drivers
 
-            self.context = sr.Context_create()
-            self.context.log_level = loglevel
-
-            self.sr_pkg_version = self.context.package_version
-            self.sr_lib_version = self.context.lib_version
+            self.sampling = False
 
         @QtCore.Slot()
         def start_sampling(self):
@@ -179,16 +175,28 @@ class SamplingThread(QtCore.QObject):
                 # is already set to 'None'.
                 return
 
-            if packet.type == sr.PacketType.ANALOG:
-                self.measured.emit(device, packet.payload)
+            if packet.type != sr.PacketType.ANALOG:
+                return
+
+            if not len(packet.payload.channels):
+                return
+
+            # TODO: find a device with multiple channels in one packet
+            channel = packet.payload.channels[0]
+
+            # the most recent value
+            value = packet.payload.data[0][-1]
+
+            self.measured.emit(device, channel,
+                    (value, packet.payload.unit, packet.payload.mq_flags))
 
     # signal used to start the worker across threads
     _start_signal = QtCore.Signal()
 
-    def __init__(self, drivers, loglevel):
+    def __init__(self, context, drivers):
         super(self.__class__, self).__init__()
 
-        self.worker = self.Worker(drivers, loglevel)
+        self.worker = self.Worker(context, drivers)
         self.thread = QtCore.QThread()
         self.worker.moveToThread(self.thread)
 
@@ -210,14 +218,6 @@ class SamplingThread(QtCore.QObject):
         self.thread.quit()
         self.thread.wait()
 
-    def sr_pkg_version(self):
-        '''Returns the version number of the libsigrok package.'''
-        return self.worker.sr_pkg_version
-
-    def sr_lib_version(self):
-        '''Returns the version number fo the libsigrok library.'''
-        return self.worker.sr_lib_version
-
 class MeasurementDataModel(QtGui.QStandardItemModel):
     '''Model to hold the measured values.'''
 
@@ -234,7 +234,7 @@ class MeasurementDataModel(QtGui.QStandardItemModel):
         # _idRole holds tuples, and using them to sort doesn't work.
         self.setSortRole(MeasurementDataModel.descRole)
 
-        # Used in 'format_mag()' to check against.
+        # Used in 'format_value()' to check against.
         self.inf = float('inf')
 
     def format_unit(self, u):
@@ -277,7 +277,7 @@ class MeasurementDataModel(QtGui.QStandardItemModel):
         else:
             return ''
 
-    def format_mag(self, mag):
+    def format_value(self, mag):
         if mag == self.inf:
             return u'\u221E'
         return '{:f}'.format(mag)
@@ -315,26 +315,19 @@ class MeasurementDataModel(QtGui.QStandardItemModel):
         self.sort(0)
         return item
 
-    @QtCore.Slot(object, object)
-    def update(self, device, payload):
+    @QtCore.Slot(object, object, object)
+    def update(self, device, channel, data):
         '''Updates the data for the device (+channel) with the most recent
         measurement from the given payload.'''
 
-        if not len(payload.channels):
-            return
-
-        # TODO: find a device with multiple channels in one packet
-        channel = payload.channels[0]
-
         item = self.getItem(device, channel)
 
-        # the most recent value
-        mag = payload.data[0][-1]
+        value, unit, mqflags = data
+        value_str = self.format_value(value)
+        unit_str = self.format_unit(unit)
+        mqflags_str = self.format_mqflags(mqflags)
 
-        unit_str = self.format_unit(payload.unit)
-        mqflags_str = self.format_mqflags(payload.mq_flags)
-        mag_str = self.format_mag(mag)
-        disp = ' '.join([mag_str, unit_str, mqflags_str])
+        disp = ' '.join([value_str, unit_str, mqflags_str])
         item.setData(disp, QtCore.Qt.DisplayRole)
 
 class MultimeterDelegate(QtGui.QStyledItemDelegate):
@@ -404,16 +397,18 @@ class EmptyMessageListView(QtGui.QListView):
 class SigrokMeter(QtGui.QMainWindow):
     '''The main window of the application.'''
 
-    def __init__(self, thread):
+    def __init__(self, context, drivers):
         super(SigrokMeter, self).__init__()
 
+        self.context = context
+
         self.delegate = MultimeterDelegate(self, self.font())
         self.model = MeasurementDataModel(self)
         self.model.rowsInserted.connect(self.modelRowsInserted)
 
         self.setup_ui()
 
-        self.thread = thread
+        self.thread = SamplingThread(self.context, drivers)
         self.thread.measured.connect(self.model.update)
         self.thread.error.connect(self.error)
         self.thread.start()
@@ -460,6 +455,10 @@ class SigrokMeter(QtGui.QMainWindow):
         self.setCentralWidget(self.listView)
         self.centralWidget().setContentsMargins(0, 0, 0, 0)
 
+    def closeEvent(self, event):
+        self.thread.stop()
+        event.accept()
+
     @QtCore.Slot()
     def show_about(self):
         text = textwrap.dedent('''\
@@ -475,7 +474,7 @@ class SigrokMeter(QtGui.QMainWindow):
                 <a href='http://www.gnu.org/licenses/gpl.html'>
                          http://www.gnu.org/licenses/gpl.html</a>
             </div>
-        '''.format(self.thread.sr_pkg_version(), self.thread.sr_lib_version()))
+        '''.format(self.context.package_version, self.context.lib_version))
 
         QtGui.QMessageBox.about(self, 'About sigrok-meter', text)
 
@@ -494,12 +493,11 @@ class SigrokMeter(QtGui.QMainWindow):
         self.listView.setMinimumHeight(dh * rows)
 
 if __name__ == '__main__':
-    thread = SamplingThread(args['drivers'], args['loglevel'])
+    context = sr.Context_create()
+    context.log_level = args['loglevel']
 
     app = QtGui.QApplication([])
-    s = SigrokMeter(thread)
+    s = SigrokMeter(context, args['drivers'])
     s.show()
 
-    r = app.exec_()
-    thread.stop()
-    sys.exit(r)
+    sys.exit(app.exec_())