X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=mainwindow.py;h=be39a4ec59f31a5ffb23efb51412d07682a1493b;hb=4946c320ea47806eb336f045c1b936df4d793683;hp=64caa2a7e9b72b03afef01d0ba4978b06aba2cc8;hpb=ac584e86982b0251970cef07d01d3646a5df4d0a;p=sigrok-meter.git diff --git a/mainwindow.py b/mainwindow.py index 64caa2a..be39a4e 100644 --- a/mainwindow.py +++ b/mainwindow.py @@ -21,11 +21,14 @@ import acquisition import datamodel +import datetime import icons import multiplotwidget import os.path import qtcompat import settings +import sigrok.core as sr +import sys import textwrap import time import util @@ -67,6 +70,9 @@ class MainWindow(QtGui.QMainWindow): self.context = context self.drivers = drivers + self.logModel = QtGui.QStringListModel(self) + self.context.set_log_callback(self._log_callback) + self.delegate = datamodel.MultimeterDelegate(self, self.font()) self.model = datamodel.MeasurementDataModel(self) @@ -100,6 +106,31 @@ class MainWindow(QtGui.QMainWindow): self.start_stop_acquisition() + def _log_callback(self, level, message): + if level.id > settings.logging.level.value().id: + return + + t = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f') + message = '[{}] sr: {}'.format(t, message) + + sys.stderr.write(message + '\n') + + scrollBar = self.logView.verticalScrollBar() + bottom = scrollBar.value() == scrollBar.maximum() + + rows = self.logModel.rowCount() + maxrows = settings.logging.lines.value() + while rows > maxrows: + self.logModel.removeRows(0, 1) + rows -= 1 + + if self.logModel.insertRow(rows): + index = self.logModel.index(rows) + self.logModel.setData(index, message, QtCore.Qt.DisplayRole) + + if bottom: + self.logView.scrollToBottom() + def _setup_ui(self): self.setWindowTitle('sigrok-meter') # Resizing the listView below will increase this again. @@ -152,10 +183,10 @@ class MainWindow(QtGui.QMainWindow): #actionAdd.setIcon(icons.add) #actionAdd.triggered.connect(self.showAddDevicePage) - #actionLog = self.sideBar.addAction('Logs') - #actionLog.setCheckable(True) - #actionLog.setIcon(icons.log) - #actionLog.triggered.connect(self.showLogPage) + actionLog = self.sideBar.addAction('Logs') + actionLog.setCheckable(True) + actionLog.setIcon(icons.log) + actionLog.triggered.connect(self.showLogPage) actionPreferences = self.sideBar.addAction('Preferences') actionPreferences.setCheckable(True) @@ -166,7 +197,7 @@ class MainWindow(QtGui.QMainWindow): self.actionGroup = QtGui.QActionGroup(self) self.actionGroup.addAction(actionGraph) #self.actionGroup.addAction(actionAdd) - #self.actionGroup.addAction(actionLog) + self.actionGroup.addAction(actionLog) self.actionGroup.addAction(actionPreferences) # show graph at startup @@ -244,8 +275,16 @@ class MainWindow(QtGui.QMainWindow): def _setup_logPage(self): self.logPage = QtGui.QWidget(self) layout = QtGui.QVBoxLayout(self.logPage) - label = QtGui.QLabel('log page') - layout.addWidget(label) + + self.logView = QtGui.QListView(self) + self.logView.setModel(self.logModel) + self.logView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) + self.logView.setSelectionMode(QtGui.QAbstractItemView.NoSelection) + layout.addWidget(self.logView) + + btn = QtGui.QPushButton('Save to file...', self) + btn.clicked.connect(self.on_save_log_clicked) + layout.addWidget(btn) def _setup_preferencesPage(self): self.preferencesPage = QtGui.QWidget(self) @@ -262,6 +301,41 @@ class MainWindow(QtGui.QMainWindow): spin.valueChanged[int].connect(settings.graph.backlog.setValue) layout.addWidget(spin, 1, 1) + layout.addWidget(QtGui.QLabel('Logging'), 2, 0) + layout.addWidget(QtGui.QLabel('Log level:'), 3, 0) + + cbox = QtGui.QComboBox() + descriptions = [ + 'no messages at all', + 'error messages', + 'warnings', + 'informational messages', + 'debug messages', + 'very noisy debug messages' + ] + for i, desc in enumerate(descriptions): + level = sr.LogLevel.get(i) + text = '{} ({})'.format(level.name, desc) + # The numeric log level corresponds to the index of the text in the + # combo box. Should this ever change, we could use the 'userData' + # that can also be stored in the item. + cbox.addItem(text) + + cbox.setCurrentIndex(settings.logging.level.value().id) + cbox.currentIndexChanged[int].connect( + (lambda i: settings.logging.level.setValue(sr.LogLevel.get(i)))) + layout.addWidget(cbox, 3, 1) + + layout.addWidget(QtGui.QLabel('Number of lines to log:'), 4, 0) + + spin = QtGui.QSpinBox(self) + spin.setMinimum(100) + spin.setMaximum(10 * 1000 * 1000) + spin.setSingleStep(100) + spin.setValue(settings.logging.lines.value()) + spin.valueChanged[int].connect(settings.logging.lines.setValue) + layout.addWidget(spin, 4, 1) + layout.setRowStretch(layout.rowCount(), 100) def showPage(self, page): @@ -428,6 +502,26 @@ class MainWindow(QtGui.QMainWindow): self.actionStartStop.setText('Stop Acquisition') self.actionStartStop.setIcon(icons.stop) + @QtCore.Slot() + def on_save_log_clicked(self): + filename = QtGui.QFileDialog.getSaveFileName(self, + 'Save Log File', settings.logging.filename.value()) + + if not filename: + # User pressed 'cancel'. + return + + try: + with open(filename, 'w') as f: + for line in self.logModel.stringList(): + f.write(line) + f.write('\n') + except Exception as e: + QtGui.QMessageBox.critical(self, 'Error saving log file', + 'Unable to save the log messages:\n{}'.format(e)) + + settings.logging.filename.setValue(filename) + @QtCore.Slot() def show_about(self): text = textwrap.dedent('''\