def setupSysTray(self): settings = Settings() settings.beginGroup(settings.keys.main) if settings.value('useSystemTrayIcon', QVariant(1)).toInt()[0]: icon = self.windowIcon() try: trayIcon = self.trayIcon except (AttributeError, ): self.trayIcon = trayIcon = QSystemTrayIcon(self) self.trayMenu = trayMenu = QMenu() trayIcon.setIcon(icon) trayMenu.addAction(icon, applicationName()) trayMenu.addSeparator() for action in self.menuFile.actions(): trayMenu.addAction(action) trayIcon.setContextMenu(trayMenu) self.connect(trayIcon, Signals.trayIconActivated, self.on_trayIcon_activated) trayIcon.show() else: try: trayIcon = self.trayIcon except (AttributeError, ): pass else: trayIcon.hide()
def setupColors(self): settings = Settings() settings.beginGroup(settings.keys.appearance) cls = ValueColorItem keys = ['increaseColor', 'neutralColor', 'decreaseColor'] attrs = [k.replace('Color', '') for k in keys] values = [QColor(settings.value(key, getattr(cls, attr))) for key, attr in zip(keys, attrs)] cls.setColors(*values)
def __init__(self, parent=None): """ Initializer. @param parent ancestor of this widget """ QFrame.__init__(self, parent) self.setupUi(self) self.settings = Settings() self.settings.beginGroup(self.settings.keys.plots) self.setupOptionsMenu() self.setupPlotsMenu() self.setupPlot()
def readSettings(self): settings = Settings() settings.beginGroup(settings.keys.main) size = settings.value(settings.keys.size, defaults.windowSize).toSize() pos = settings.value(settings.keys.position, defaults.windowPosition).toPoint() maxed = settings.value(settings.keys.maximized, False).toBool() self.resize(size) self.move(pos) if maxed: self.showMaximized() state = settings.value(settings.keys.winstate, QVariant()) self.restoreState(state.toByteArray()) settings.endGroup()
def readSettings(self): """ Reads selected keys from saved settings. @return None """ settings = Settings() settings.beginGroup(settings.keys.account) keys = settings.value(self.settingKey) if keys.isValid(): keys = [[str(b) for b in a.toStringList()] for a in keys.toList()] else: keys = self.defaultKeys setup = self.dataModel.setAccountKeyDisplay for key, currency in keys: setup(key, currency, True, self.summaryView)
def updateRecentSessions(self): settings = Settings() settings.beginGroup(settings.keys.main) files = settings.value('recentSessions').toStringList() files = set([abspath(str(s)) for s in files]) files = list(files) count = min(len(files), self.maxRecentSessions) for i in range(count): text = files[i] action = self.recentSessionsActions[i] action.setText(basename(str(text))) action.setData(QVariant(text)) action.setVisible(True) for i in range(count, self.maxRecentSessions): action = self.recentSessionsActions[i] action.setVisible(False) self.recentSeparator.setVisible(count > 0)
def setCurrentSession(self, filename): settings = Settings() settings.beginGroup(settings.keys.main) files = settings.value('recentSessions').toStringList() files.removeAll(filename) files.prepend(filename) files = files[:self.maxRecentSessions] settings.setValue('recentSessions', files) self.updateRecentSessions()
def setSessionPlot(self, session, collection, tickerId, *args): """ Associate a session with this instance. @param session Session instance @param tickerId id of ticker as integer @param *indexes unused @return None """ self.sessionArgs = (session, collection, tickerId, args) if not self.plotWidgets: settings = Settings() settings.beginGroup("Plots") settings.beginGroup("%s" % tickerId) # count = settings.value('displaycount', QVariant(1)).toInt()[0] count = 1 for i in range(count): self.addPlot() else: for plot in self.plotWidgets: plot.setSessionPlot(session, collection, tickerId, *args)
def checkClose(self): check = True settings = Settings() settings.beginGroup(settings.keys.main) confirm = settings.value('confirmCloseWhenModified', QVariant(1)) confirm = confirm.toInt()[0] if self.session.isModified() and confirm: buttons = QMessageBox.Save|QMessageBox.Discard|QMessageBox.Cancel text = 'This session has been modified' if self.session.isConnected(): text += ' and is connected and receiving messages.' else: text += '.' text += '\n\nDo you want to save your changes?' msg = QMessageBox.question( self, applicationName(), text, buttons, QMessageBox.Save) if msg == QMessageBox.Discard: pass elif msg == QMessageBox.Cancel: check = False elif msg == QMessageBox.Save: self.actionSaveSession.trigger() return check
def saveSettings(self): """ Signal handler for last window closing. Saves selected keys. @return None """ settings = Settings() settings.beginGroup(settings.keys.account) keys = [QVariant([key, currency]) for (key, currency), item in self.sharedKeys.items() if item is not None] settings.setValue(self.settingKey, keys)
def readSettings(self): """ Applies stored setting values to instance. @return None """ self.settings = obj = Settings() obj.beginGroup(obj.keys.designer) self.resize(obj.value(obj.keys.size, defaults.windowSize).toSize()) self.move( obj.value(obj.keys.position, defaults.windowPosition).toPoint()) if obj.value(obj.keys.maximized, False).toBool(): self.showMaximized() self.restoreState( obj.value(obj.keys.winstate, QVariant()).toByteArray()) self.splitter.restoreState( obj.value(obj.keys.splitstate, QVariant()).toByteArray())
def on_actionStrategyDesigner_triggered(self): from profit.strategydesigner.main import StrategyDesigner settings = Settings() settings.beginGroup(settings.keys.strategy) if settings.value('type', '').toString()=='file': filename = settings.value('location', '').toString() def x(name): print '## strategy file named %s updated' % (name, ) else: def x(name): print "## strategy file updated but i don't care" filename = None win = StrategyDesigner(filename=filename, parent=self) win.show()
def urlActions(self, symbol): settings = Settings() settings.beginGroup(settings.keys.urls) urls = settings.value(settings.keys.tickerurls, defaults.tickerUrls()) settings.endGroup() urls = [str(s) for s in defaults.tickerUrls()] actions = [] for url in urls: #urls.toStringList(): try: name, url = str(url).split(':', 1) url = Template(url).substitute(symbol=symbol) except ( KeyError, ValueError, ): continue action = makeUrlAction(name, url, toolTip='%s %s' % (symbol, name)) actions.append(action) return actions
def urlActions(self, symbol): settings = Settings() settings.beginGroup(settings.keys.urls) urls = settings.value(settings.keys.tickerurls, defaults.tickerUrls()) settings.endGroup() urls = [str(s) for s in defaults.tickerUrls()] actions = [] for url in urls: #urls.toStringList(): try: name, url = str(url).split(':', 1) url = Template(url).substitute(symbol=symbol) except (KeyError, ValueError, ): continue action = makeUrlAction(name, url, toolTip='%s %s' % (symbol, name)) actions.append(action) return actions
def setSessionPlot(self, session, collection, tickerId, *args): """ Associate a session with this instance. @param session Session instance @param tickerId id of ticker as integer @param *indexes unused @return None """ self.sessionArgs = (session, collection, tickerId, args) if not self.plotWidgets: settings = Settings() settings.beginGroup('Plots') settings.beginGroup('%s' % tickerId) #count = settings.value('displaycount', QVariant(1)).toInt()[0] count = 1 for i in range(count): self.addPlot() else: for plot in self.plotWidgets: plot.setSessionPlot(session, collection, tickerId, *args)
def on_actionClearRecentMenu_triggered(self, checked=False): for action in self.recentSessionsActions: action.setVisible(False) settings = Settings() settings.beginGroup(settings.keys.main) settings.remove('recentSessions')
def saveCount(self): settings = Settings() settings.beginGroup('Plots') settings.beginGroup('%s' % self.sessionArgs[1].__class__.__name__) settings.setValue('displaycount', len(self.plotWidgets))
class Plot(QFrame, Ui_Plot): """ Plot container. """ def __init__(self, parent=None): """ Initializer. @param parent ancestor of this widget """ QFrame.__init__(self, parent) self.setupUi(self) self.settings = Settings() self.settings.beginGroup(self.settings.keys.plots) self.setupOptionsMenu() self.setupPlotsMenu() self.setupPlot() def setupOptionsMenu(self): """ Configure the options button menu. @return None """ self.dataDialog = None optionsButton = self.optionsButton pop = QMenu(optionsButton) optionsButton.setMenu(pop) pop.addAction(self.actionDrawMajorX) pop.addAction(self.actionDrawMajorY) pop.addAction(self.actionChangeMajorGridStyle) pop.addSeparator() pop.addAction(self.actionDrawMinorX) pop.addAction(self.actionDrawMinorY) pop.addAction(self.actionChangeMinorGridStyle) pop.addSeparator() pop.addAction(self.actionShowDataDialog) pop.addAction(self.actionDrawLegend) pop.addAction(self.actionChangeCanvasColor) def setupPlotsMenu(self): """ Configure the plots button menu. @return None """ plotButton = self.plotButton pop = QMenu(plotButton) plotButton.setMenu(pop) pop.addAction(self.actionNewPlot) pop.addAction(self.actionClosePlot) pop.addSeparator() pop.addAction(self.actionSyncWithData) def setupPlot(self): """ Configure the plot widget. @return None """ pen = QPen(Qt.black) plot = self.plot plot.setFrameStyle(plot.NoFrame | plot.Plain) plot.insertLegend(Legend(), plot.LeftLegend) canvas = plot.canvas() canvas.setFrameStyle(plot.NoFrame | plot.Plain) layout = plot.plotLayout() layout.setCanvasMargin(0) layout.setAlignCanvasToScales(True) self.grid = PlotGrid() self.grid.attach(plot) self.panner = PlotPanner(canvas) self.zoomer = PlotZoomer(canvas) self.zoomer.setRubberBandPen(pen) self.picker = PlotPicker(canvas) self.picker.setTrackerPen(pen) self.connect(self.zoomer, Signals.zoomed, self.on_zoomer_zoomed) self.enableAutoScale() def setSessionPlot(self, session, collection, key, *indexes): """ Associate a session with this instance. @param session Session instance @param key id of ticker as integer @param *indexes unused @return None """ self.controlsTreeItems = [] self.highlightMarkers = [] self.session = session self.collection = collection self.key = key settings = self.settings name = self.plotName() statekey = '%s/%s' % (name, settings.keys.splitstate) state = settings.value(statekey, defaults.rightSplitterState()) self.plotSplitter.restoreState(state.toByteArray()) self.setupTree() self.loadGrids() self.loadSelections() self.loadCanvasColor() self.loadLegend() self.updateAxis() scaler = self.plot.axisScaleEngine(xBottom) scaler.setMargins(0.0, 0.05) axisactions = [self.actionChangeAxesFont, self.actionChangeAxesColor] for widget in self.axisWidgets(): widget.addActions(axisactions) widget.setContextMenuPolicy(Qt.ActionsContextMenu) color = settings.value('%s/axiscolor' % name) if color.isValid(): self.setAxisColor(QColor(color)) font = settings.value('%s/axisfont' % name) if font.isValid(): self.setAxisFont(QFont(font)) self.plot.replot() if settings.value('%s/datadialog' % name).toBool(): ## tab might not be available QTimer.singleShot(500, self.actionShowDataDialog.trigger) session.registerMeta(self) def setupTree(self): """ Configure the model and initial items for this instance. @return None """ tree = self.controlsTree self.controlsTreeModel = model = QStandardItemModel(self) tree.setModel(model) model.setHorizontalHeaderLabels(['Line', 'Value']) tree.sortByColumn(0, Qt.AscendingOrder) try: ticker = self.collection[self.key] except ( KeyError, TypeError, ): pass else: for field, series in ticker.series.items(): self.addSeries(TickType.getField(field), series) self.connect(model, Signals.standardItemChanged, self.on_controlsTree_itemChanged) for col in range(model.columnCount()): tree.resizeColumnToContents(col) tree.addActions([ self.actionChangeCurveStyle, self.actionChangeDataMarker, self.actionChangeCurveAxisX, self.actionChangeCurveAxisY, ]) tree.expandAll() def addSeries(self, name, series, parent=None, items=[], checkable=True): """ Creates new controls and curve for an individual series. @param name series key @return None """ try: name + () except (TypeError, ): key = name else: key = '/'.join(name) name = name[0] if parent is None: parent = self.controlsTreeModel.invisibleRootItem() item = ControlTreeItem(name, series, key, checkable=checkable) self.controlsTreeItems.append(item) if not items: items = [ ControlTreeValueItem(''), ] parent.appendRow([ item, ] + items) if checkable: item.setColor(self.loadItemPen(item).color()) for index in getattr(series, 'indexes', []): self.addSeries(index.key, index, parent=item) self.loadSelection(item) return item def anyCheckedItems(self): """ True if any control is checked. """ return bool(self.checkedItems()) def axisWidgets(self): """ Yields each plot axis widget. """ for axis in allAxes: yield self.plot.axisWidget(axis) def checkedItems(self): """ Sequence of checked controls. """ return [item for item in self.controlsTreeItems if item.isChecked()] def checkedNames(self): """ Sequence of checked control names. """ return [self.itemName(item) for item in self.checkedItems()] def on_zoomer_zoomed(self, rect): """ Sets autoscaling mode when plot is zoomed to its base. @param rect ignored @return None """ if not self.zoomer.zoomRectIndex(): self.enableAutoScale() def enableAutoScale(self): """ Sets autoscaling mode on all four axes. @return None """ for axis in allAxes: self.plot.setAxisAutoScale(axis) def enableCurve(self, item, enable=True): """ Sets the visibility and style of a plot curve. @param item tree widget item @param enabled sets curve visible if True, otherwise invisible @return None """ curve = item.curve curve.hide() plot = self.plot legend = plot.legend() drawLegend = self.actionDrawLegend if enable: if not curve.settingsLoaded: self.loadCurve(self.itemName(item), curve) curve.setData(item.data.x, item.data.y) curve.attach(plot) if self.actionDrawLegend.isChecked(): curve.updateLegend(legend, True) curve.show() else: legend.remove(curve) curve.detach() self.emit(Signals.enableCurve, item, enable) checked = self.anyCheckedItems() self.actionDrawLegend.setEnabled(checked) if not checked: legend.clear() legend.hide() plot.updateAxes() plot.replot() def getAxisColor(self): """ Returns the foreground color of the axis widgets. @return QColor instance """ widget = self.referenceAxisWidget() palette = widget.palette() return palette.color(palette.WindowText) def itemName(self, item): """ Name for given item, including name of this plot. @param item ControlTreeItem instance @return name full item name including plot name """ return '%s/%s' % (self.plotName(), item.name()) def loadCanvasColor(self): """ Reads and sets the canvas color from saved settings. @return None """ color = self.settings.value('%s/canvascolor' % self.plotName(), defaults.canvasColor()) self.plot.setCanvasBackground(QColor(color)) def loadCurve(self, name, curve): """ Reads and configures a plot curve. @param name of curve @param curve QwtPlotCurve instance @return None """ getv = self.settings.value curve.setBrush(QBrush(getv('%s/brush' % name, QBrush()))) curve.setPen(QPen(getv('%s/pen' % name, QPen()))) curve.setStyle( curve.CurveStyle( getv('%s/style' % name, QVariant(curve.Lines)).toInt()[0])) curve.setBaseline( getv('%s/baseline' % name, QVariant(0.0)).toDouble()[0]) curve.setCurveAttribute(curve.Inverted, getv('%s/inverted' % name).toBool()) curve.setCurveAttribute(curve.Fitted, getv('%s/fitted' % name).toBool()) curve.setPaintAttribute(curve.PaintFiltered, getv('%s/filtered' % name).toBool()) curve.setPaintAttribute(curve.ClipPolygons, getv('%s/clippoly' % name).toBool()) curve.setXAxis( QwtPlot.Axis(getv('%s/xaxis' % name, xBottom).toInt()[0])) curve.setYAxis(QwtPlot.Axis( getv('%s/yaxis' % name, yRight).toInt()[0])) def applySymbol(symname, symobj): symobj.setBrush(QBrush(getv('%s/brush' % symname, QBrush()))) symobj.setPen(QPen(getv('%s/pen' % symname, QPen()))) style = getv('%s/style' % symname, QVariant(symobj.NoSymbol)) symobj.setStyle(symobj.Style(style.toInt()[0])) symobj.setSize(getv('%s/size' % symname).toSize()) applySymbol('%s/symbol' % name, curve.symbol()) curve.dataMarker = marker = PlotDataMarker() marksym = QwtSymbol() applySymbol('%s/dataselect/symbol' % name, marksym) marker.setSymbol(marksym) markstyle = getv('%s/dataselect/style' % name, PlotDataMarker.VLine) marker.setLineStyle(marker.LineStyle(markstyle.toInt()[0])) marker.setLinePen(QPen(getv('%s/dataselect/pen' % name, Qt.red))) curve.settingsLoaded = True def loadGrids(self): """ Reads and sets the major and minor grid pens and visibility. @return None """ name = self.plotName() grid = self.grid getv = self.settings.value pen = getv('%s/major/pen' % name, defaults.majorGridPen()) grid.setMajPen(QPen(pen)) pen = getv('%s/minor/pen' % name, defaults.minorGridPen()) grid.setMinPen(QPen(pen)) items = [('%s/major/x/enabled', self.actionDrawMajorX), ('%s/major/y/enabled', self.actionDrawMajorY), ('%s/minor/x/enabled', self.actionDrawMinorX), ('%s/minor/y/enabled', self.actionDrawMinorY)] for key, action in items: v = getv(key % name) if not v.isValid() or v.toBool(): action.trigger() def loadItemPen(self, item): """ Creates a pen from saved settings. @param item ControlTreeItem instance @return QPen instance """ pen = self.settings.value('%s/pen' % self.itemName(item)) if pen.isValid(): pen = QPen(pen) else: pen = defaults.itemPen(item.name()) return pen def loadLegend(self): """ Restores the plot legend visibility from saved settings. """ key = '%s/legend/enabled' % self.plotName() if self.settings.value(key).toBool(): self.actionDrawLegend.trigger() def loadSelection(self, item): """ Restores an item check state and pen from saved settings. """ key = '%s/checkeditems' % self.plotName() if self.itemName(item) in self.settings.valueLoad(key, ''): item.setCheckState(Qt.Checked) item.setColor(self.loadItemPen(item).color()) def loadSelections(self): """ Restores each control tree item check state and pen. """ for item in self.controlsTreeItems: self.loadSelection(item) def saveSelections(self): """ Saves the selected control item names. """ key = '%s/checkeditems' % self.plotName() names = self.checkedNames() if names: # don't save an empty list because the user might be # closing an empty plot that really does have selections # saved in the settings. self.settings.setValueDump(key, names) def plotName(self): """ The name of this plot. """ try: return '%s/%s' % (self.key, self.objectName()) except (AttributeError, ): return 'noname/%s' % (self.objectName(), ) def referenceAxisWidget(self): """ Returns a referece axis widget. """ return self.plot.axisWidget(xBottom) def saveCanvasColor(self): """ Saves the canvas background color to user settings. @return None """ prefix = self.plotName() self.settings.setValue('%s/canvascolor' % prefix, self.plot.canvasBackground()) def saveCurve(self, name, curve): """ Saves visual settings of a curve. @param name curve name, used as settings key @param curve QwtPlotCurve instance @return None """ setv = self.settings.setValue setv('%s/brush' % name, curve.brush()) setv('%s/pen' % name, curve.pen()) setv('%s/style' % name, curve.style()) setv('%s/baseline' % name, curve.baseline()) setv('%s/inverted' % name, curve.testCurveAttribute(curve.Inverted)) setv('%s/fitted' % name, curve.testCurveAttribute(curve.Fitted)) setv('%s/filtered' % name, curve.testPaintAttribute(curve.PaintFiltered)) setv('%s/clippoly' % name, curve.testPaintAttribute(curve.ClipPolygons)) setv('%s/xaxis' % name, curve.xAxis()) setv('%s/yaxis' % name, curve.yAxis()) name = '%s/symbol' % name symbol = curve.symbol() setv('%s/brush' % name, symbol.brush()) setv('%s/pen' % name, symbol.pen()) setv('%s/style' % name, symbol.style()) setv('%s/size' % name, symbol.size()) def saveMarker(self, name, marker): """ Saves visual settings of a marker. @param name curve name, used as settings key @param curve QwtPlotMarker instance @return None """ setv = self.settings.setValue setv('%s/dataselect/style' % name, marker.lineStyle()) setv('%s/dataselect/pen' % name, marker.linePen()) symname = '%s/dataselect/symbol' % name symbol = marker.symbol() setv('%s/brush' % symname, symbol.brush()) setv('%s/pen' % symname, symbol.pen()) setv('%s/style' % symname, symbol.style()) setv('%s/size' % symname, symbol.size()) def saveLegend(self): """ Saves the visibility of the plot legend to user settings. @return None """ key = '%s/legend/enabled' % self.plotName() self.settings.setValue(key, self.actionDrawLegend.isChecked()) def saveMajorX(self): """ Saves the state and pen of the major grid x axis. @return None """ name = self.plotName() setv = self.settings.setValue setv('%s/major/x/enabled' % name, self.actionDrawMajorX.isChecked()) setv('%s/major/pen' % name, self.grid.majPen()) def saveMajorY(self): """ Saves the state and pen of the major grid y axis. @return None """ name = self.plotName() setv = self.settings.setValue setv('%s/major/y/enabled' % name, self.actionDrawMajorY.isChecked()) setv('%s/major/pen' % name, self.grid.majPen()) def saveMinorX(self): """ Saves the state and pen of the minor grid x axis. @return None """ name = self.plotName() setv = self.settings.setValue setv('%s/minor/x/enabled' % name, self.actionDrawMinorX.isChecked()) setv('%s/minor/pen' % name, self.grid.minPen()) def saveMinorY(self): """ Saves the state and pen of the minor grid y axis. @return None """ name = self.plotName() setv = self.settings.setValue setv('%s/minor/y/enabled' % name, self.actionDrawMinorY.isChecked()) setv('%s/minor/pen' % name, self.grid.minPen()) def setAxisColor(self, color): """ Sets the axis widgets foreground and text color. @param color QColor instance @return None """ for widget in self.axisWidgets(): palette = widget.palette() palette.setColor(palette.WindowText, color) palette.setColor(palette.Text, color) widget.setPalette(palette) def setAxisFont(self, font): """ Sets the axis widgets font. @param font QFont instance @return None """ for widget in self.axisWidgets(): widget.setFont(font) def updateAxis(self): """ Enables each y axis if there are curves attached to it. @return None """ enable = self.plot.enableAxis items = self.checkedItems() for pair, pred in [([yRight, yLeft], lambda i, a: i.curve.yAxis() == a), ([xTop, xBottom], lambda i, a: i.curve.xAxis() == a)]: for axis in pair: enable(axis, any(item for item in items if pred(item, axis))) ## session signal handlers def on_session_createdSeries(self, key, field): """ Signal handler called when new Series objects are created. @param key id of ticker with new series @param field series field """ if key != self.key: return series = self.collection[self.key].series[field] self.addSeries(TickType.getField(field), series) self.controlsTree.sortByColumn(0, Qt.AscendingOrder) def setItemValue(self, item): idx = self.controlsTreeModel.indexFromItem(item) parent = item.parent() if parent: getc = parent.child else: getc = self.controlsTreeModel.item next = getc(item.row(), item.column() + 1) try: next.setText('%.2f' % item.data[-1]) except ( AttributeError, IndexError, TypeError, ): pass else: for c in [item.child(r, 0) for r in range(item.rowCount())]: self.setItemValue(c) def on_session_TickPrice_TickSize(self, message): """ Signal handler for TickPrice and TickSize session messages. @param message Message instance @return None """ if message.tickerId != self.key: return for item in self.controlsTreeItems: self.setItemValue(item) items = [i for i in self.controlsTreeItems if i.curve.isVisible()] for item in items: item.curve.setData(item.data.x, item.data.y) if items: self.plot.replot() self.on_zoomer_zoomed(None) def on_session_UpdateAccountValue(self, message): if self.key != 'account': return items = [i for i in self.controlsTreeItems if i.curve.isVisible()] for item in items: item.curve.setData(item.data.x, item.data.y) if items: self.plot.replot() self.on_zoomer_zoomed(None) ## action signal handlers @pyqtSignature('') def on_actionChangeCurveStyle_triggered(self): """ Signal handler called to edit a curve. @return None """ pos = self.sender().data().toPoint() index = self.controlsTree.indexAt(pos) if index.isValid(): item = self.controlsTreeModel.itemFromIndex(index) indexZero = self.controlsTreeModel.sibling(index.row(), 0, index) first = self.controlsTreeModel.itemFromIndex(indexZero) try: curve = first.curve color = first.color except (AttributeError, ): return else: item = first if not curve.settingsLoaded: self.loadCurve(self.itemName(item), curve) cplot = curve.plot() if cplot is None: curve.attach(self.plot) dlg = PlotItemDialog(curve, self) if dlg.exec_() == dlg.Accepted: dlg.applyToCurve(curve) item.setColor(curve.pen().color()) self.saveCurve(self.itemName(item), curve) self.enableCurve(item, enable=item.checkState() == Qt.Checked) if cplot is None: curve.detach() @pyqtSignature('') def on_actionChangeCurveAxisX_triggered(self): """ Signal handler called to toggle the x axis of a curve. """ pos = self.sender().data().toPoint() index = self.controlsTree.indexAt(pos) if index.isValid(): item = self.controlsTreeModel.itemFromIndex(index) curve = item.curve if curve.xAxis() == xTop: curve.setXAxis(xBottom) else: curve.setXAxis(xTop) self.updateAxis() self.saveCurve(self.itemName(item), curve) self.plot.replot() @pyqtSignature('') def on_actionChangeCurveAxisY_triggered(self): """ Signal handler called to toggle the y axis of a curve. @return None """ pos = self.sender().data().toPoint() index = self.controlsTree.indexAt(pos) if index.isValid(): item = self.controlsTreeModel.itemFromIndex(index) curve = item.curve if curve.yAxis() == yLeft: curve.setYAxis(yRight) else: curve.setYAxis(yLeft) self.updateAxis() self.saveCurve(self.itemName(item), curve) self.plot.replot() @pyqtSignature('') def on_actionChangeDataMarker_triggered(self): """ Signal handler called to edit data marker. @return None """ pos = self.sender().data().toPoint() index = self.controlsTree.indexAt(pos) if index.isValid(): item = self.controlsTreeModel.itemFromIndex(index) curve = item.curve if not curve.settingsLoaded: self.loadCurve(self.itemName(item), curve) cplot = curve.plot() if cplot is None: curve.attach(self.plot) dlg = PlotItemDialog(curve, marker=curve.dataMarker, parent=self) if dlg.exec_() == dlg.Accepted: dlg.applyToMarker(curve.dataMarker) self.saveMarker(self.itemName(item), curve.dataMarker) for marker in self.highlightMarkers: marker.restyleFrom(curve.dataMarker) self.plot.replot() if cplot is None: curve.detach() @pyqtSignature('bool') def on_actionDrawLegend_triggered(self, enable): """ Signal handler called to toggle the plot legend visibility. @param enable if True, legend is enabled @return False """ legend = self.plot.legend() legend.setVisible(enable) if enable: items = self.checkedItems() if items: for item in items: item.curve.updateLegend(legend, True) else: self.actionDrawLegend.setChecked(False) else: legend.clear() self.saveLegend() @pyqtSignature('bool') def on_actionDrawMajorX_triggered(self, enable): """ Signal handler called to toggle visiblity of major grid x axis. @param enable if True, grid axis is enabled @return None """ self.grid.enableX(enable) self.plot.replot() self.saveMajorX() @pyqtSignature('bool') def on_actionDrawMajorY_triggered(self, enable): """ Signal handler called to toggle visiblity of major grid y axis. @param enable if True, grid axis is enabled @return None """ self.grid.enableY(enable) self.plot.replot() self.saveMajorY() @pyqtSignature('bool') def on_actionDrawMinorX_triggered(self, enable): """ Signal handler called to toggle visiblity of minor grid x axis. @param enable if True, grid axis is enabled @return None """ self.grid.enableXMin(enable) self.plot.replot() self.saveMinorX() @pyqtSignature('bool') def on_actionDrawMinorY_triggered(self, enable): """ Signal handler called to toggle visiblity of minor grid y axis. @param enable if True, grid axis is enabled @return None """ self.grid.enableYMin(enable) self.plot.replot() self.saveMinorY() @pyqtSignature('') def on_actionChangeMajorGridStyle_triggered(self): """ Signal handler called to edit the major grid pen. @return None """ pen = changePen(self.grid.majPen, self.grid.setMajPen, self) if pen: self.plot.replot() self.saveMajorX() self.saveMajorY() @pyqtSignature('') def on_actionChangeMinorGridStyle_triggered(self): """ Signal handler called to edit the minor grid pen. @return None """ pen = changePen(self.grid.minPen, self.grid.setMinPen, self) if pen: self.plot.replot() self.saveMinorX() self.saveMinorY() @pyqtSignature('') def on_actionChangeCanvasColor_triggered(self): """ Signal handler called to edit the plot canvas background. @return None """ plot = self.plot color = changeColor(plot.canvasBackground, plot.setCanvasBackground, self) if color: pen = QPen(complementColor(color)) self.zoomer.setRubberBandPen(pen) self.picker.setTrackerPen(pen) plot.replot() self.saveCanvasColor() @pyqtSignature('') def on_actionChangeAxesFont_triggered(self): """ Signal handler called to edit the axes font. @return None """ widget = self.referenceAxisWidget() default = widget.font() font, okay = QFontDialog.getFont(default, self, 'Select Axis Font') if okay: self.setAxisFont(font) self.settings.setValue('%s/axisfont' % self.plotName(), font) @pyqtSignature('') def on_actionChangeAxesColor_triggered(self): """ Signal handler called to edit the axes color. @return None """ color = changeColor(self.getAxisColor, self.setAxisColor, self) if color: self.settings.setValue('%s/axiscolor' % self.plotName(), color) @pyqtSignature('bool') def on_actionShowDataDialog_triggered(self, enable): """ Signal handler called to show or hide the data dialog. @return None """ if enable: dlg = self.dataDialog = PlotDataDialog(self) try: tabs = self.window().centralTabs except (AttributeError, ): pass else: name = tabs.tabText(tabs.currentIndex()) dlg.setWindowTitle(str(dlg.windowTitle()) % name) dlg.setWindowIcon(tabs.tabIcon(tabs.currentIndex())) self.connect(dlg, Signals.dialogFinished, self.on_dataDialog_finished) self.connect(dlg, Signals.highlightSelections, self.on_dataDialog_selected) dlg.show() elif self.dataDialog: self.dataDialog.close() self.dataDialog = None self.settings.setValue('%s/datadialog' % self.plotName(), enable) ## controls tree signal handlers def on_controlsTree_doubleClicked(self, index): """ Signal handler for control tree double click. @param index QModelIndex instance @return None """ tree = self.controlsTree if index.isValid(): pos = tree.visualRect(index).center() actions = tree.actions() for action in actions: action.setData(QVariant(pos)) self.actionChangeCurveStyle.trigger() def on_controlsTree_itemChanged(self, item): """ Signal handler for all changes to control tree items. @param item changed tree widget item @return None """ try: curve = item.curve except (AttributeError, ): pass else: self.enableCurve(item, enable=item.checkState() == Qt.Checked) self.updateAxis() self.saveSelections() def on_controlsTree_customContextMenuRequested(self, pos): """ Signal handler for context menu request over control tree. @param pos QPoint of mouse click @return None """ tree = self.controlsTree index = tree.indexAt(pos) if index.isValid(): item = self.controlsTreeModel.itemFromIndex(index) if not hasattr(item, 'curve'): return if item.curve.yAxis() == yRight: self.actionChangeCurveAxisY.setText('Move to Left Axis') else: self.actionChangeCurveAxisY.setText('Move to Right Axis') if item.curve.xAxis() == xTop: self.actionChangeCurveAxisX.setText('Move to Bottom Axis') else: self.actionChangeCurveAxisX.setText('Move to Top Axis') actions = tree.actions() for action in actions: action.setData(QVariant(pos)) QMenu.exec_(actions, tree.mapToGlobal(pos)) def on_dataDialog_finished(self, result): """ Signal handler for data dialog finish. Sets and saves state of data dialog display after its closed. @param result ignored @return None """ self.actionShowDataDialog.setChecked(False) self.dataDialog = None self.on_dataDialog_selected([]) self.settings.setValue('%s/datadialog' % self.plotName(), False) def on_dataDialog_selected(self, items): """ Signal handler for data dialog selection changes. @params items list of (index, item) two-tuples @return None """ for marker in self.highlightMarkers: marker.detach() self.highlightMarkers = markers = [] for index, item in items: try: x, y = index.row(), item.data[index.row()] except (IndexError, ): continue if x is None or y is None: continue curve = item.curve marker = curve.dataMarker.cloneFromValue(curve, x, y) markers.append(marker) marker.attach(self.plot) self.plot.replot() def on_plotSplitter_splitterMoved(self, pos, index): """ Signal handler for splitter move; saves state to user settings. @param pos ignored @param index ignored @return None """ settings = self.settings statekey = '%s/%s' % (self.plotName(), settings.keys.splitstate) settings.setValue(statekey, self.plotSplitter.saveState()) def syncPlot(self, sync=None): print '## sync?', sync session = self.session (session.registerMeta if sync else session.deregisterMeta)(self)
def writeSettings(self): """ Saves some main window settings. """ settings = Settings() settings.beginGroup(settings.keys.main) settings.setValue(settings.keys.size, self.size()) settings.setValue(settings.keys.position, self.pos()) settings.setValue(settings.keys.maximized, self.isMaximized()) settings.setValue(settings.keys.winstate, self.saveState()) settings.setValueDump(settings.keys.ctabstate, self.centralTabState()) settings.endGroup()
def saveCount(self): settings = Settings() settings.beginGroup("Plots") settings.beginGroup("%s" % self.sessionArgs[1].__class__.__name__) settings.setValue("displaycount", len(self.plotWidgets))
@pyqtSignature('') def on_tickerUrlUp_clicked(self): self.moveTickerUrl(-1) @pyqtSignature('') def on_tickerUrlDown_clicked(self): self.moveTickerUrl(1) def moveTickerUrl(self, offset): widget = self.tickerUrls item = widget.currentItem() other = widget.item(widget.currentRow() + offset) itemtext, othertext = item.text(), other.text() item.setText(othertext) other.setText(itemtext) selmodel = widget.selectionModel() selmodel.clear() selmodel.setCurrentIndex(widget.indexFromItem(other), selmodel.Select) def accept(self): self.writeSettings(Settings()) QDialog.accept(self) if __name__ == '__main__': app = QApplication([]) win = SettingsDialog() win.readSettings(Settings()) win.exec_()
def accept(self): self.writeSettings(Settings()) QDialog.accept(self)
class Plot(QFrame, Ui_Plot): """ Plot container. """ def __init__(self, parent=None): """ Initializer. @param parent ancestor of this widget """ QFrame.__init__(self, parent) self.setupUi(self) self.settings = Settings() self.settings.beginGroup(self.settings.keys.plots) self.setupOptionsMenu() self.setupPlotsMenu() self.setupPlot() def setupOptionsMenu(self): """ Configure the options button menu. @return None """ self.dataDialog = None optionsButton = self.optionsButton pop = QMenu(optionsButton) optionsButton.setMenu(pop) pop.addAction(self.actionDrawMajorX) pop.addAction(self.actionDrawMajorY) pop.addAction(self.actionChangeMajorGridStyle) pop.addSeparator() pop.addAction(self.actionDrawMinorX) pop.addAction(self.actionDrawMinorY) pop.addAction(self.actionChangeMinorGridStyle) pop.addSeparator() pop.addAction(self.actionShowDataDialog) pop.addAction(self.actionDrawLegend) pop.addAction(self.actionChangeCanvasColor) def setupPlotsMenu(self): """ Configure the plots button menu. @return None """ plotButton = self.plotButton pop = QMenu(plotButton) plotButton.setMenu(pop) pop.addAction(self.actionNewPlot) pop.addAction(self.actionClosePlot) pop.addSeparator() pop.addAction(self.actionSyncWithData) def setupPlot(self): """ Configure the plot widget. @return None """ pen = QPen(Qt.black) plot = self.plot plot.setFrameStyle(plot.NoFrame|plot.Plain) plot.insertLegend(Legend(), plot.LeftLegend) canvas = plot.canvas() canvas.setFrameStyle(plot.NoFrame|plot.Plain) layout = plot.plotLayout() layout.setCanvasMargin(0) layout.setAlignCanvasToScales(True) self.grid = PlotGrid() self.grid.attach(plot) self.panner = PlotPanner(canvas) self.zoomer = PlotZoomer(canvas) self.zoomer.setRubberBandPen(pen) self.picker = PlotPicker(canvas) self.picker.setTrackerPen(pen) self.connect(self.zoomer, Signals.zoomed, self.on_zoomer_zoomed) self.enableAutoScale() def setSessionPlot(self, session, collection, key, *indexes): """ Associate a session with this instance. @param session Session instance @param key id of ticker as integer @param *indexes unused @return None """ self.controlsTreeItems = [] self.highlightMarkers = [] self.session = session self.collection = collection self.key = key settings = self.settings name = self.plotName() statekey = '%s/%s' % (name, settings.keys.splitstate) state = settings.value(statekey, defaults.rightSplitterState()) self.plotSplitter.restoreState(state.toByteArray()) self.setupTree() self.loadGrids() self.loadSelections() self.loadCanvasColor() self.loadLegend() self.updateAxis() scaler = self.plot.axisScaleEngine(xBottom) scaler.setMargins(0.0, 0.05) axisactions = [self.actionChangeAxesFont, self.actionChangeAxesColor] for widget in self.axisWidgets(): widget.addActions(axisactions) widget.setContextMenuPolicy(Qt.ActionsContextMenu) color = settings.value('%s/axiscolor' % name) if color.isValid(): self.setAxisColor(QColor(color)) font = settings.value('%s/axisfont' % name) if font.isValid(): self.setAxisFont(QFont(font)) self.plot.replot() if settings.value('%s/datadialog' % name).toBool(): ## tab might not be available QTimer.singleShot(500, self.actionShowDataDialog.trigger) session.registerMeta(self) def setupTree(self): """ Configure the model and initial items for this instance. @return None """ tree = self.controlsTree self.controlsTreeModel = model = QStandardItemModel(self) tree.setModel(model) model.setHorizontalHeaderLabels(['Line', 'Value']) tree.sortByColumn(0, Qt.AscendingOrder) try: ticker = self.collection[self.key] except (KeyError, TypeError, ): pass else: for field, series in ticker.series.items(): self.addSeries(TickType.getField(field), series) self.connect(model, Signals.standardItemChanged, self.on_controlsTree_itemChanged) for col in range(model.columnCount()): tree.resizeColumnToContents(col) tree.addActions( [self.actionChangeCurveStyle, self.actionChangeDataMarker, self.actionChangeCurveAxisX, self.actionChangeCurveAxisY,]) tree.expandAll() def addSeries(self, name, series, parent=None, items=[], checkable=True): """ Creates new controls and curve for an individual series. @param name series key @return None """ try: name + () except (TypeError, ): key = name else: key = '/'.join(name) name = name[0] if parent is None: parent = self.controlsTreeModel.invisibleRootItem() item = ControlTreeItem(name, series, key, checkable=checkable) self.controlsTreeItems.append(item) if not items: items = [ControlTreeValueItem(''), ] parent.appendRow([item, ] + items) if checkable: item.setColor(self.loadItemPen(item).color()) for index in getattr(series, 'indexes', []): self.addSeries(index.key, index, parent=item) self.loadSelection(item) return item def anyCheckedItems(self): """ True if any control is checked. """ return bool(self.checkedItems()) def axisWidgets(self): """ Yields each plot axis widget. """ for axis in allAxes: yield self.plot.axisWidget(axis) def checkedItems(self): """ Sequence of checked controls. """ return [item for item in self.controlsTreeItems if item.isChecked()] def checkedNames(self): """ Sequence of checked control names. """ return [self.itemName(item) for item in self.checkedItems()] def on_zoomer_zoomed(self, rect): """ Sets autoscaling mode when plot is zoomed to its base. @param rect ignored @return None """ if not self.zoomer.zoomRectIndex(): self.enableAutoScale() def enableAutoScale(self): """ Sets autoscaling mode on all four axes. @return None """ for axis in allAxes: self.plot.setAxisAutoScale(axis) def enableCurve(self, item, enable=True): """ Sets the visibility and style of a plot curve. @param item tree widget item @param enabled sets curve visible if True, otherwise invisible @return None """ curve = item.curve curve.hide() plot = self.plot legend = plot.legend() drawLegend = self.actionDrawLegend if enable: if not curve.settingsLoaded: self.loadCurve(self.itemName(item), curve) curve.setData(item.data.x, item.data.y) curve.attach(plot) if self.actionDrawLegend.isChecked(): curve.updateLegend(legend, True) curve.show() else: legend.remove(curve) curve.detach() self.emit(Signals.enableCurve, item, enable) checked = self.anyCheckedItems() self.actionDrawLegend.setEnabled(checked) if not checked: legend.clear() legend.hide() plot.updateAxes() plot.replot() def getAxisColor(self): """ Returns the foreground color of the axis widgets. @return QColor instance """ widget = self.referenceAxisWidget() palette = widget.palette() return palette.color(palette.WindowText) def itemName(self, item): """ Name for given item, including name of this plot. @param item ControlTreeItem instance @return name full item name including plot name """ return '%s/%s' % (self.plotName(), item.name()) def loadCanvasColor(self): """ Reads and sets the canvas color from saved settings. @return None """ color = self.settings.value( '%s/canvascolor' % self.plotName(), defaults.canvasColor()) self.plot.setCanvasBackground(QColor(color)) def loadCurve(self, name, curve): """ Reads and configures a plot curve. @param name of curve @param curve QwtPlotCurve instance @return None """ getv = self.settings.value curve.setBrush(QBrush(getv('%s/brush' % name, QBrush()))) curve.setPen(QPen(getv('%s/pen' % name, QPen()))) curve.setStyle(curve.CurveStyle( getv('%s/style' % name, QVariant(curve.Lines)).toInt()[0])) curve.setBaseline( getv('%s/baseline' % name, QVariant(0.0)).toDouble()[0]) curve.setCurveAttribute( curve.Inverted, getv('%s/inverted' % name).toBool()) curve.setCurveAttribute( curve.Fitted, getv('%s/fitted' % name).toBool()) curve.setPaintAttribute( curve.PaintFiltered, getv('%s/filtered' % name).toBool()) curve.setPaintAttribute( curve.ClipPolygons, getv('%s/clippoly' % name).toBool()) curve.setXAxis( QwtPlot.Axis(getv('%s/xaxis' % name, xBottom).toInt()[0])) curve.setYAxis( QwtPlot.Axis(getv('%s/yaxis' % name, yRight).toInt()[0])) def applySymbol(symname, symobj): symobj.setBrush(QBrush(getv('%s/brush' % symname, QBrush()))) symobj.setPen(QPen(getv('%s/pen' % symname, QPen()))) style = getv('%s/style' % symname, QVariant(symobj.NoSymbol)) symobj.setStyle(symobj.Style(style.toInt()[0])) symobj.setSize(getv('%s/size' % symname).toSize()) applySymbol('%s/symbol' % name, curve.symbol()) curve.dataMarker = marker = PlotDataMarker() marksym = QwtSymbol() applySymbol('%s/dataselect/symbol' % name, marksym) marker.setSymbol(marksym) markstyle = getv('%s/dataselect/style' % name, PlotDataMarker.VLine) marker.setLineStyle(marker.LineStyle(markstyle.toInt()[0])) marker.setLinePen(QPen(getv('%s/dataselect/pen' % name, Qt.red))) curve.settingsLoaded = True def loadGrids(self): """ Reads and sets the major and minor grid pens and visibility. @return None """ name = self.plotName() grid = self.grid getv = self.settings.value pen = getv('%s/major/pen' % name, defaults.majorGridPen()) grid.setMajPen(QPen(pen)) pen = getv('%s/minor/pen' % name, defaults.minorGridPen()) grid.setMinPen(QPen(pen)) items = [('%s/major/x/enabled', self.actionDrawMajorX), ('%s/major/y/enabled', self.actionDrawMajorY), ('%s/minor/x/enabled', self.actionDrawMinorX), ('%s/minor/y/enabled', self.actionDrawMinorY)] for key, action in items: v = getv(key % name) if not v.isValid() or v.toBool(): action.trigger() def loadItemPen(self, item): """ Creates a pen from saved settings. @param item ControlTreeItem instance @return QPen instance """ pen = self.settings.value('%s/pen' % self.itemName(item)) if pen.isValid(): pen = QPen(pen) else: pen = defaults.itemPen(item.name()) return pen def loadLegend(self): """ Restores the plot legend visibility from saved settings. """ key = '%s/legend/enabled' % self.plotName() if self.settings.value(key).toBool(): self.actionDrawLegend.trigger() def loadSelection(self, item): """ Restores an item check state and pen from saved settings. """ key = '%s/checkeditems' % self.plotName() if self.itemName(item) in self.settings.valueLoad(key, ''): item.setCheckState(Qt.Checked) item.setColor(self.loadItemPen(item).color()) def loadSelections(self): """ Restores each control tree item check state and pen. """ for item in self.controlsTreeItems: self.loadSelection(item) def saveSelections(self): """ Saves the selected control item names. """ key = '%s/checkeditems' % self.plotName() names = self.checkedNames() if names: # don't save an empty list because the user might be # closing an empty plot that really does have selections # saved in the settings. self.settings.setValueDump(key, names) def plotName(self): """ The name of this plot. """ try: return '%s/%s' % (self.key, self.objectName()) except (AttributeError, ): return 'noname/%s' % (self.objectName(), ) def referenceAxisWidget(self): """ Returns a referece axis widget. """ return self.plot.axisWidget(xBottom) def saveCanvasColor(self): """ Saves the canvas background color to user settings. @return None """ prefix = self.plotName() self.settings.setValue( '%s/canvascolor' % prefix, self.plot.canvasBackground()) def saveCurve(self, name, curve): """ Saves visual settings of a curve. @param name curve name, used as settings key @param curve QwtPlotCurve instance @return None """ setv = self.settings.setValue setv('%s/brush' % name, curve.brush()) setv('%s/pen' % name, curve.pen()) setv('%s/style' % name, curve.style()) setv('%s/baseline' % name, curve.baseline()) setv('%s/inverted' % name, curve.testCurveAttribute(curve.Inverted)) setv('%s/fitted' % name, curve.testCurveAttribute(curve.Fitted)) setv('%s/filtered' % name, curve.testPaintAttribute(curve.PaintFiltered)) setv('%s/clippoly' % name, curve.testPaintAttribute(curve.ClipPolygons)) setv('%s/xaxis' % name, curve.xAxis()) setv('%s/yaxis' % name, curve.yAxis()) name = '%s/symbol' % name symbol = curve.symbol() setv('%s/brush' % name, symbol.brush()) setv('%s/pen' % name, symbol.pen()) setv('%s/style' % name, symbol.style()) setv('%s/size' % name, symbol.size()) def saveMarker(self, name, marker): """ Saves visual settings of a marker. @param name curve name, used as settings key @param curve QwtPlotMarker instance @return None """ setv = self.settings.setValue setv('%s/dataselect/style' % name, marker.lineStyle()) setv('%s/dataselect/pen' % name, marker.linePen()) symname = '%s/dataselect/symbol' % name symbol = marker.symbol() setv('%s/brush' % symname, symbol.brush()) setv('%s/pen' % symname, symbol.pen()) setv('%s/style' % symname, symbol.style()) setv('%s/size' % symname, symbol.size()) def saveLegend(self): """ Saves the visibility of the plot legend to user settings. @return None """ key = '%s/legend/enabled' % self.plotName() self.settings.setValue(key, self.actionDrawLegend.isChecked()) def saveMajorX(self): """ Saves the state and pen of the major grid x axis. @return None """ name = self.plotName() setv = self.settings.setValue setv('%s/major/x/enabled' % name, self.actionDrawMajorX.isChecked()) setv('%s/major/pen' % name, self.grid.majPen()) def saveMajorY(self): """ Saves the state and pen of the major grid y axis. @return None """ name = self.plotName() setv = self.settings.setValue setv('%s/major/y/enabled' % name, self.actionDrawMajorY.isChecked()) setv('%s/major/pen' % name, self.grid.majPen()) def saveMinorX(self): """ Saves the state and pen of the minor grid x axis. @return None """ name = self.plotName() setv = self.settings.setValue setv('%s/minor/x/enabled' % name, self.actionDrawMinorX.isChecked()) setv('%s/minor/pen' % name, self.grid.minPen()) def saveMinorY(self): """ Saves the state and pen of the minor grid y axis. @return None """ name = self.plotName() setv = self.settings.setValue setv('%s/minor/y/enabled' % name, self.actionDrawMinorY.isChecked()) setv('%s/minor/pen' % name, self.grid.minPen()) def setAxisColor(self, color): """ Sets the axis widgets foreground and text color. @param color QColor instance @return None """ for widget in self.axisWidgets(): palette = widget.palette() palette.setColor(palette.WindowText, color) palette.setColor(palette.Text, color) widget.setPalette(palette) def setAxisFont(self, font): """ Sets the axis widgets font. @param font QFont instance @return None """ for widget in self.axisWidgets(): widget.setFont(font) def updateAxis(self): """ Enables each y axis if there are curves attached to it. @return None """ enable = self.plot.enableAxis items = self.checkedItems() for pair, pred in [ ([yRight, yLeft], lambda i, a:i.curve.yAxis()==a), ([xTop, xBottom], lambda i, a:i.curve.xAxis()==a)]: for axis in pair: enable(axis, any(item for item in items if pred(item, axis))) ## session signal handlers def on_session_createdSeries(self, key, field): """ Signal handler called when new Series objects are created. @param key id of ticker with new series @param field series field """ if key != self.key: return series = self.collection[self.key].series[field] self.addSeries(TickType.getField(field), series) self.controlsTree.sortByColumn(0, Qt.AscendingOrder) def setItemValue(self, item): idx = self.controlsTreeModel.indexFromItem(item) parent = item.parent() if parent: getc = parent.child else: getc = self.controlsTreeModel.item next = getc(item.row(), item.column()+1) try: next.setText('%.2f' % item.data[-1]) except (AttributeError, IndexError, TypeError, ): pass else: for c in [item.child(r, 0) for r in range(item.rowCount())]: self.setItemValue(c) def on_session_TickPrice_TickSize(self, message): """ Signal handler for TickPrice and TickSize session messages. @param message Message instance @return None """ if message.tickerId != self.key: return for item in self.controlsTreeItems: self.setItemValue(item) items = [i for i in self.controlsTreeItems if i.curve.isVisible()] for item in items: item.curve.setData(item.data.x, item.data.y) if items: self.plot.replot() self.on_zoomer_zoomed(None) def on_session_UpdateAccountValue(self, message): if self.key != 'account': return items = [i for i in self.controlsTreeItems if i.curve.isVisible()] for item in items: item.curve.setData(item.data.x, item.data.y) if items: self.plot.replot() self.on_zoomer_zoomed(None) ## action signal handlers @pyqtSignature('') def on_actionChangeCurveStyle_triggered(self): """ Signal handler called to edit a curve. @return None """ pos = self.sender().data().toPoint() index = self.controlsTree.indexAt(pos) if index.isValid(): item = self.controlsTreeModel.itemFromIndex(index) indexZero = self.controlsTreeModel.sibling(index.row(), 0, index) first = self.controlsTreeModel.itemFromIndex(indexZero) try: curve = first.curve color = first.color except (AttributeError, ): return else: item = first if not curve.settingsLoaded: self.loadCurve(self.itemName(item), curve) cplot = curve.plot() if cplot is None: curve.attach(self.plot) dlg = PlotItemDialog(curve, self) if dlg.exec_() == dlg.Accepted: dlg.applyToCurve(curve) item.setColor(curve.pen().color()) self.saveCurve(self.itemName(item), curve) self.enableCurve(item, enable=item.checkState()==Qt.Checked) if cplot is None: curve.detach() @pyqtSignature('') def on_actionChangeCurveAxisX_triggered(self): """ Signal handler called to toggle the x axis of a curve. """ pos = self.sender().data().toPoint() index = self.controlsTree.indexAt(pos) if index.isValid(): item = self.controlsTreeModel.itemFromIndex(index) curve = item.curve if curve.xAxis() == xTop: curve.setXAxis(xBottom) else: curve.setXAxis(xTop) self.updateAxis() self.saveCurve(self.itemName(item), curve) self.plot.replot() @pyqtSignature('') def on_actionChangeCurveAxisY_triggered(self): """ Signal handler called to toggle the y axis of a curve. @return None """ pos = self.sender().data().toPoint() index = self.controlsTree.indexAt(pos) if index.isValid(): item = self.controlsTreeModel.itemFromIndex(index) curve = item.curve if curve.yAxis() == yLeft: curve.setYAxis(yRight) else: curve.setYAxis(yLeft) self.updateAxis() self.saveCurve(self.itemName(item), curve) self.plot.replot() @pyqtSignature('') def on_actionChangeDataMarker_triggered(self): """ Signal handler called to edit data marker. @return None """ pos = self.sender().data().toPoint() index = self.controlsTree.indexAt(pos) if index.isValid(): item = self.controlsTreeModel.itemFromIndex(index) curve = item.curve if not curve.settingsLoaded: self.loadCurve(self.itemName(item), curve) cplot = curve.plot() if cplot is None: curve.attach(self.plot) dlg = PlotItemDialog(curve, marker=curve.dataMarker, parent=self) if dlg.exec_() == dlg.Accepted: dlg.applyToMarker(curve.dataMarker) self.saveMarker(self.itemName(item), curve.dataMarker) for marker in self.highlightMarkers: marker.restyleFrom(curve.dataMarker) self.plot.replot() if cplot is None: curve.detach() @pyqtSignature('bool') def on_actionDrawLegend_triggered(self, enable): """ Signal handler called to toggle the plot legend visibility. @param enable if True, legend is enabled @return False """ legend = self.plot.legend() legend.setVisible(enable) if enable: items = self.checkedItems() if items: for item in items: item.curve.updateLegend(legend, True) else: self.actionDrawLegend.setChecked(False) else: legend.clear() self.saveLegend() @pyqtSignature('bool') def on_actionDrawMajorX_triggered(self, enable): """ Signal handler called to toggle visiblity of major grid x axis. @param enable if True, grid axis is enabled @return None """ self.grid.enableX(enable) self.plot.replot() self.saveMajorX() @pyqtSignature('bool') def on_actionDrawMajorY_triggered(self, enable): """ Signal handler called to toggle visiblity of major grid y axis. @param enable if True, grid axis is enabled @return None """ self.grid.enableY(enable) self.plot.replot() self.saveMajorY() @pyqtSignature('bool') def on_actionDrawMinorX_triggered(self, enable): """ Signal handler called to toggle visiblity of minor grid x axis. @param enable if True, grid axis is enabled @return None """ self.grid.enableXMin(enable) self.plot.replot() self.saveMinorX() @pyqtSignature('bool') def on_actionDrawMinorY_triggered(self, enable): """ Signal handler called to toggle visiblity of minor grid y axis. @param enable if True, grid axis is enabled @return None """ self.grid.enableYMin(enable) self.plot.replot() self.saveMinorY() @pyqtSignature('') def on_actionChangeMajorGridStyle_triggered(self): """ Signal handler called to edit the major grid pen. @return None """ pen = changePen(self.grid.majPen, self.grid.setMajPen, self) if pen: self.plot.replot() self.saveMajorX() self.saveMajorY() @pyqtSignature('') def on_actionChangeMinorGridStyle_triggered(self): """ Signal handler called to edit the minor grid pen. @return None """ pen = changePen(self.grid.minPen, self.grid.setMinPen, self) if pen: self.plot.replot() self.saveMinorX() self.saveMinorY() @pyqtSignature('') def on_actionChangeCanvasColor_triggered(self): """ Signal handler called to edit the plot canvas background. @return None """ plot = self.plot color = changeColor( plot.canvasBackground, plot.setCanvasBackground, self) if color: pen = QPen(complementColor(color)) self.zoomer.setRubberBandPen(pen) self.picker.setTrackerPen(pen) plot.replot() self.saveCanvasColor() @pyqtSignature('') def on_actionChangeAxesFont_triggered(self): """ Signal handler called to edit the axes font. @return None """ widget = self.referenceAxisWidget() default = widget.font() font, okay = QFontDialog.getFont(default, self, 'Select Axis Font') if okay: self.setAxisFont(font) self.settings.setValue( '%s/axisfont' % self.plotName(), font) @pyqtSignature('') def on_actionChangeAxesColor_triggered(self): """ Signal handler called to edit the axes color. @return None """ color = changeColor(self.getAxisColor, self.setAxisColor, self) if color: self.settings.setValue('%s/axiscolor' % self.plotName(), color) @pyqtSignature('bool') def on_actionShowDataDialog_triggered(self, enable): """ Signal handler called to show or hide the data dialog. @return None """ if enable: dlg = self.dataDialog = PlotDataDialog(self) try: tabs = self.window().centralTabs except (AttributeError, ): pass else: name = tabs.tabText(tabs.currentIndex()) dlg.setWindowTitle(str(dlg.windowTitle()) % name) dlg.setWindowIcon(tabs.tabIcon(tabs.currentIndex())) self.connect( dlg, Signals.dialogFinished, self.on_dataDialog_finished) self.connect( dlg, Signals.highlightSelections, self.on_dataDialog_selected) dlg.show() elif self.dataDialog: self.dataDialog.close() self.dataDialog = None self.settings.setValue('%s/datadialog' % self.plotName(), enable) ## controls tree signal handlers def on_controlsTree_doubleClicked(self, index): """ Signal handler for control tree double click. @param index QModelIndex instance @return None """ tree = self.controlsTree if index.isValid(): pos = tree.visualRect(index).center() actions = tree.actions() for action in actions: action.setData(QVariant(pos)) self.actionChangeCurveStyle.trigger() def on_controlsTree_itemChanged(self, item): """ Signal handler for all changes to control tree items. @param item changed tree widget item @return None """ try: curve = item.curve except (AttributeError, ): pass else: self.enableCurve(item, enable=item.checkState()==Qt.Checked) self.updateAxis() self.saveSelections() def on_controlsTree_customContextMenuRequested(self, pos): """ Signal handler for context menu request over control tree. @param pos QPoint of mouse click @return None """ tree = self.controlsTree index = tree.indexAt(pos) if index.isValid(): item = self.controlsTreeModel.itemFromIndex(index) if not hasattr(item, 'curve'): return if item.curve.yAxis() == yRight: self.actionChangeCurveAxisY.setText('Move to Left Axis') else: self.actionChangeCurveAxisY.setText('Move to Right Axis') if item.curve.xAxis() == xTop: self.actionChangeCurveAxisX.setText('Move to Bottom Axis') else: self.actionChangeCurveAxisX.setText('Move to Top Axis') actions = tree.actions() for action in actions: action.setData(QVariant(pos)) QMenu.exec_(actions, tree.mapToGlobal(pos)) def on_dataDialog_finished(self, result): """ Signal handler for data dialog finish. Sets and saves state of data dialog display after its closed. @param result ignored @return None """ self.actionShowDataDialog.setChecked(False) self.dataDialog = None self.on_dataDialog_selected([]) self.settings.setValue('%s/datadialog' % self.plotName(), False) def on_dataDialog_selected(self, items): """ Signal handler for data dialog selection changes. @params items list of (index, item) two-tuples @return None """ for marker in self.highlightMarkers: marker.detach() self.highlightMarkers = markers = [] for index, item in items: try: x, y = index.row(), item.data[index.row()] except (IndexError, ): continue if x is None or y is None: continue curve = item.curve marker = curve.dataMarker.cloneFromValue(curve, x, y) markers.append(marker) marker.attach(self.plot) self.plot.replot() def on_plotSplitter_splitterMoved(self, pos, index): """ Signal handler for splitter move; saves state to user settings. @param pos ignored @param index ignored @return None """ settings = self.settings statekey = '%s/%s' % (self.plotName(), settings.keys.splitstate) settings.setValue(statekey, self.plotSplitter.saveState()) def syncPlot(self, sync=None): print '## sync?', sync session = self.session (session.registerMeta if sync else session.deregisterMeta)(self)
def on_actionSettings_triggered(self): from profit.workbench.settingsdialog import SettingsDialog dlg = SettingsDialog() dlg.readSettings(Settings()) if dlg.exec_() == dlg.Accepted: self.emit(Signals.settingsChanged)