X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mainwindow.py;h=680dd97b5eb5cded0d7cb7ba4b2ad304298975d7;hb=2abf5a93f7fbca40d4b761e34c4edee008a6b37d;hp=315d805ceed1d124931b2397b8b632f967df0db5;hpb=2e8c2e6e68049604c25a5f035ff4c71513bce31b;p=sigrok-meter.git diff --git a/mainwindow.py b/mainwindow.py index 315d805..680dd97 100644 --- a/mainwindow.py +++ b/mainwindow.py @@ -21,9 +21,11 @@ import acquisition import datamodel +import icons import multiplotwidget import os.path import qtcompat +import settings import textwrap import time import util @@ -70,9 +72,17 @@ class MainWindow(QtGui.QMainWindow): self.delegate = datamodel.MultimeterDelegate(self, self.font()) self.model = datamodel.MeasurementDataModel(self) - self.model.rowsInserted.connect(self.modelRowsInserted) - self.setup_ui() + # Maps from 'unit' to the corresponding plot. + self._plots = {} + # Maps from '(plot, device)' to the corresponding curve. + self._curves = {} + + self._setup_ui() + + self._plot_update_timer = QtCore.QTimer() + self._plot_update_timer.setInterval(MainWindow.UPDATEINTERVAL) + self._plot_update_timer.timeout.connect(self._updatePlots) QtCore.QTimer.singleShot(0, self._start_acquisition) @@ -89,70 +99,179 @@ class MainWindow(QtGui.QMainWindow): self.close() return - self.acquisition.start() + self.start_stop_acquisition() - def setup_ui(self): + def _setup_ui(self): self.setWindowTitle('sigrok-meter') # Resizing the listView below will increase this again. self.resize(350, 10) - p = os.path.abspath(os.path.dirname(__file__)) - p = os.path.join(p, 'sigrok-logo-notext.png') - self.setWindowIcon(QtGui.QIcon(p)) + self.setWindowIcon(QtGui.QIcon(':/logo.png')) - actionQuit = QtGui.QAction(self) - actionQuit.setText('&Quit') - actionQuit.setIcon(QtGui.QIcon.fromTheme('application-exit')) - actionQuit.setShortcut('Ctrl+Q') - actionQuit.triggered.connect(self.close) + self._setup_graphPage() + self._setup_addDevicePage() + self._setup_logPage() + self._setup_preferencesPage() - actionAbout = QtGui.QAction(self) - actionAbout.setText('&About') - actionAbout.setIcon(QtGui.QIcon.fromTheme('help-about')) - actionAbout.triggered.connect(self.show_about) + self._pages = [ + self.graphPage, + self.addDevicePage, + self.logPage, + self.preferencesPage + ] - menubar = self.menuBar() - menuFile = menubar.addMenu('&File') - menuFile.addAction(actionQuit) - menuHelp = menubar.addMenu('&Help') - menuHelp.addAction(actionAbout) - - self.listView = EmptyMessageListView('waiting for data...') - self.listView.setFrameShape(QtGui.QFrame.NoFrame) - self.listView.viewport().setBackgroundRole(QtGui.QPalette.Window) - self.listView.viewport().setAutoFillBackground(True) - self.listView.setMinimumWidth(260) - self.listView.setSelectionMode(QtGui.QAbstractItemView.NoSelection) - self.listView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) - self.listView.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) - self.listView.setItemDelegate(self.delegate) - self.listView.setModel(self.model) - self.listView.setUniformItemSizes(True) - self.listView.setMinimumSize(self.delegate.sizeHint()) + self.stackedWidget = QtGui.QStackedWidget(self) + for page in self._pages: + self.stackedWidget.addWidget(page) - self.plotwidget = multiplotwidget.MultiPlotWidget(self) - self.plotwidget.plotHidden.connect(self._on_plotHidden) + self._setup_sidebar() - # Maps from 'unit' to the corresponding plot. - self._plots = {} - # Maps from '(plot, device)' to the corresponding curve. - self._curves = {} + self.setCentralWidget(QtGui.QWidget()) + self.centralWidget().setContentsMargins(0, 0, 0, 0) - self.splitter = QtGui.QSplitter(QtCore.Qt.Horizontal); - self.splitter.addWidget(self.listView) - self.splitter.addWidget(self.plotwidget) - self.splitter.setStretchFactor(0, 0) - self.splitter.setStretchFactor(1, 1) + layout = QtGui.QHBoxLayout(self.centralWidget()) + layout.addWidget(self.sideBar) + layout.addWidget(self.stackedWidget) + layout.setSpacing(0) + layout.setContentsMargins(0, 0, 0, 0) + + self.resize(settings.mainwindow.size.value()) + if settings.mainwindow.pos.value(): + self.move(settings.mainwindow.pos.value()) + + def _setup_sidebar(self): + self.sideBar = QtGui.QToolBar(self) + self.sideBar.setOrientation(QtCore.Qt.Vertical) + + actionGraph = self.sideBar.addAction('Instantaneous Values and Graphs') + actionGraph.setCheckable(True) + actionGraph.setIcon(icons.graph) + actionGraph.triggered.connect(self.showGraphPage) + + #actionAdd = self.sideBar.addAction('Add Device') + #actionAdd.setCheckable(True) + #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) + + #actionPreferences = self.sideBar.addAction('Preferences') + #actionPreferences.setCheckable(True) + #actionPreferences.setIcon(icons.preferences) + #actionPreferences.triggered.connect(self.showPreferencesPage) + + # make the buttons at the top exclusive + self.actionGroup = QtGui.QActionGroup(self) + self.actionGroup.addAction(actionGraph) + #self.actionGroup.addAction(actionAdd) + #self.actionGroup.addAction(actionLog) + #self.actionGroup.addAction(actionPreferences) + + # show graph at startup + actionGraph.setChecked(True) + + # fill space between buttons on the top and on the bottom + fill = QtGui.QWidget(self) + fill.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) + self.sideBar.addWidget(fill) + + self.actionStartStop = self.sideBar.addAction('Start Acquisition') + self.actionStartStop.setIcon(icons.start) + self.actionStartStop.triggered.connect(self.start_stop_acquisition) + + actionAbout = self.sideBar.addAction('About') + actionAbout.setIcon(icons.about) + actionAbout.triggered.connect(self.show_about) - self.setCentralWidget(self.splitter) - self.centralWidget().setContentsMargins(0, 0, 0, 0) - self.resize(800, 500) + actionQuit = self.sideBar.addAction('Quit') + actionQuit.setIcon(icons.exit) + actionQuit.triggered.connect(self.close) + + s = self.style().pixelMetric(QtGui.QStyle.PM_LargeIconSize) + self.sideBar.setIconSize(QtCore.QSize(s, s)) + + self.sideBar.setStyleSheet(''' + QToolBar { + background-color: white; + margin: 0px; + border: 0px; + border-right: 1px solid black; + } + + QToolButton { + padding: 10px; + border: 0px; + border-right: 1px solid black; + } + + QToolButton:checked, + QToolButton[checkable="false"]:hover { + background-color: #c0d0e8; + } + ''') + + def _setup_graphPage(self): + listView = EmptyMessageListView('waiting for data...') + listView.setFrameShape(QtGui.QFrame.NoFrame) + listView.viewport().setBackgroundRole(QtGui.QPalette.Window) + listView.viewport().setAutoFillBackground(True) + listView.setMinimumWidth(260) + listView.setSelectionMode(QtGui.QAbstractItemView.NoSelection) + listView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) + listView.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) + listView.setItemDelegate(self.delegate) + listView.setModel(self.model) + listView.setUniformItemSizes(True) + listView.setMinimumSize(self.delegate.sizeHint()) - self.startTimer(MainWindow.UPDATEINTERVAL) + self.plotwidget = multiplotwidget.MultiPlotWidget(self) + self.plotwidget.plotHidden.connect(self._on_plotHidden) - def stop(self): - self.acquisition.stop() - print(self.acquisition.is_running()) + self.graphPage = QtGui.QSplitter(QtCore.Qt.Horizontal, self) + self.graphPage.addWidget(listView) + self.graphPage.addWidget(self.plotwidget) + self.graphPage.setStretchFactor(0, 0) + self.graphPage.setStretchFactor(1, 1) + + def _setup_addDevicePage(self): + self.addDevicePage = QtGui.QWidget(self) + layout = QtGui.QVBoxLayout(self.addDevicePage) + label = QtGui.QLabel('add device page') + layout.addWidget(label) + + def _setup_logPage(self): + self.logPage = QtGui.QWidget(self) + layout = QtGui.QVBoxLayout(self.logPage) + label = QtGui.QLabel('log page') + layout.addWidget(label) + + def _setup_preferencesPage(self): + self.preferencesPage = QtGui.QWidget(self) + layout = QtGui.QVBoxLayout(self.preferencesPage) + label = QtGui.QLabel('preferences page') + layout.addWidget(label) + + def showPage(self, page): + self.stackedWidget.setCurrentIndex(self._pages.index(page)) + + @QtCore.Slot(bool) + def showGraphPage(self): + self.showPage(self.graphPage) + + @QtCore.Slot(bool) + def showAddDevicePage(self): + self.showPage(self.addDevicePage) + + @QtCore.Slot(bool) + def showLogPage(self): + self.showPage(self.logPage) + + @QtCore.Slot(bool) + def showPreferencesPage(self): + self.showPage(self.preferencesPage) def _getPlot(self, unit): '''Looks up or creates a new plot for 'unit'.''' @@ -177,7 +296,7 @@ class MainWindow(QtGui.QMainWindow): def _getCurve(self, plot, deviceID): '''Looks up or creates a new curve for '(plot, deviceID)'.''' - key = (id(plot), deviceID) + key = (plot, deviceID) if key in self._curves: return self._curves[key] @@ -193,11 +312,6 @@ class MainWindow(QtGui.QMainWindow): self._curves[key] = curve return curve - def timerEvent(self, event): - '''Periodically updates all graphs.''' - - self._updatePlots() - def _updatePlots(self): '''Updates all plots.''' @@ -252,16 +366,43 @@ class MainWindow(QtGui.QMainWindow): @QtCore.Slot() def _stopped(self): if self._closing: + # The acquisition was stopped by the 'closeEvent()', close the + # window again now that the acquisition has stopped. self.close() def closeEvent(self, event): if self.acquisition.is_running(): + # Stop the acquisition before closing the window. self._closing = True - self.acquisition.stop() + self.start_stop_acquisition() event.ignore() else: + settings.mainwindow.size.setValue(self.size()) + settings.mainwindow.pos.setValue(self.pos()) event.accept() + @QtCore.Slot() + def start_stop_acquisition(self): + if self.acquisition.is_running(): + self.acquisition.stop() + self._plot_update_timer.stop() + self.actionStartStop.setText('Start Acquisition') + self.actionStartStop.setIcon(icons.start) + else: + # before starting (again), remove all old samples and old curves + self.model.clear_samples() + + for key in self._curves: + plot, _ = key + curve = self._curves[key] + plot.view.removeItem(curve) + self._curves = {} + + self.acquisition.start() + self._plot_update_timer.start() + self.actionStartStop.setText('Stop Acquisition') + self.actionStartStop.setIcon(icons.stop) + @QtCore.Slot() def show_about(self): text = textwrap.dedent('''\ @@ -276,15 +417,11 @@ class MainWindow(QtGui.QMainWindow): This program comes with ABSOLUTELY NO WARRANTY;
for details visit - http://www.gnu.org/licenses/gpl.html + http://www.gnu.org/licenses/gpl.html
+
+ Some icons by + the GNOME project '''.format(self.context.package_version, self.context.lib_version)) QtGui.QMessageBox.about(self, 'About sigrok-meter', text) - - @QtCore.Slot(object, int, int) - def modelRowsInserted(self, parent, start, end): - '''Resize the list view to the size of the content.''' - rows = self.model.rowCount() - dh = self.delegate.sizeHint().height() - self.listView.setMinimumHeight(dh * rows)