summaryrefslogtreecommitdiff
path: root/lib/taurus/qt/qtgui/plot/qwtdialog.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/taurus/qt/qtgui/plot/qwtdialog.py')
-rw-r--r--lib/taurus/qt/qtgui/plot/qwtdialog.py505
1 files changed, 505 insertions, 0 deletions
diff --git a/lib/taurus/qt/qtgui/plot/qwtdialog.py b/lib/taurus/qt/qtgui/plot/qwtdialog.py
new file mode 100644
index 00000000..65fac896
--- /dev/null
+++ b/lib/taurus/qt/qtgui/plot/qwtdialog.py
@@ -0,0 +1,505 @@
+#!/usr/bin/env python
+
+#############################################################################
+##
+## This file is part of Taurus
+##
+## http://taurus-scada.org
+##
+## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
+##
+## Taurus is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Taurus is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with Taurus. If not, see <http://www.gnu.org/licenses/>.
+##
+#############################################################################
+
+"""
+qwtdialog.py: Dialogs for Taurusplot
+"""
+
+import time
+
+from taurus.external.qt import Qt, Qwt5
+from taurus.qt.qtgui.util.ui import UILoadable
+
+
+#class TaurusPlotConfigCapable:
+# """This class is aimed to act as an interface for class TaurusPlot. Every class that uses
+# TaurusPlotConfigDialog class (as TaurusPlot does) should inherit TaurusPlotConfigCapable class
+# and overwrite the methods defined below in order to avoid firing exceptions"""
+# def __init__(self, parent = None):
+# pass
+#
+# def showConfigDialog(self):
+# raise NotImplementedError, "TaurusPlotConfigCapable: method showConfigDialog() not implemented in child class"
+#
+# def setAxisScale(self,axis,min,max):
+# raise NotImplementedError, "TaurusPlotConfigCapable: method setAxisScale() not implemented in child class"
+#
+# def setAxisAutoScale(self, axis=None):
+# raise NotImplementedError, "TaurusPlotConfigCapable: method setAxisAutoScale() not implemented in child class"
+#
+# def setAxisScaleType(self, axis=None, scale=None):
+# raise NotImplementedError, "TaurusPlotConfigCapable: method setAxisScaleType() not implemented in child class"
+
+
+@UILoadable(with_ui='ui')
+class TaurusPlotConfigDialog(Qt.QDialog):
+ """This class is used to build and manage the plot configuration dialog. It
+ has been designed using the qt designer application, and then loaded to this
+ widget. Hence, if you need to modify the dialog, you can use the
+ TaurusPlotConfigDialog.ui file (under ui directory) to make it easier."""
+
+ def __init__(self, parent=None, flags=Qt.Qt.WindowFlags()):
+ self.parent = parent
+ #if parent==None or not isinstance(parent, TaurusPlotConfigCapable):
+ # raise NotImplementedError, "Parent object doesn't implement TaurusPlotConfigCapable class"
+ #call qt designer generated functions to initialize GUI
+ Qt.QDialog.__init__(self, parent, flags)
+ self.loadUi()
+
+ #insert the CurvesAppearanceWidget
+ #(@TODO:must be changed to be done directly in the ui, but I couldn't make the widget available to TaurusDesigner)
+ from curvesAppearanceChooserDlg import CurvesAppearanceChooser
+ layout=Qt.QVBoxLayout()
+ self.curvesAppearanceChooser=CurvesAppearanceChooser(None)
+ layout.addWidget(self.curvesAppearanceChooser)
+ self.ui.curveAppearanceGB.setLayout(layout)
+
+ #set the values for the CurvesAppearanceChooser
+ self.curvesAppearanceChooser.setCurves(self.parent.getCurveAppearancePropertiesDict())
+
+ #insert valid values into mode combobox (linear or logarihtmic) and set selected one in combobox
+ self.ui.xModeComboBox.insertItem(0,"Linear")
+ self.ui.xModeComboBox.insertItem(1,"Logarithmic")
+ self.ui.y1ModeComboBox.insertItem(0,"Linear")
+ self.ui.y1ModeComboBox.insertItem(1,"Logarithmic")
+ self.ui.y2ModeComboBox.insertItem(0,"Linear")
+ self.ui.y2ModeComboBox.insertItem(1,"Logarithmic")
+
+ #insert valid values into peaks combobox (max, min or both) and set selected one in combobox
+ self.ui.peaksComboBox.insertItem(0,"Both")
+ self.ui.peaksComboBox.insertItem(1,"Max")
+ self.ui.peaksComboBox.insertItem(2,"Min")
+ self.ui.peaksComboBox.insertItem(3,"None")
+
+ #Init X axis group
+ self.ui.xRangeCB.setVisible(False)
+ self.ui.xLabelRange.setVisible(False)
+ if self.parent.getXIsTime():
+ # adapt the X axis group for time-based measurements
+ self.ui.xRangeCB.addItems(["",
+ "1 m",
+ "1 h",
+ "1 d",
+ "1 w",
+ "30 d",
+ "1 y"])
+ self.ui.xGroupBox.setTitle("Time")
+ self.ui.xLabelMin.setText("Start")
+ self.ui.xLabelMax.setText("End")
+ timetooltip="""It accepts both absolute data-times (e.g. "25/10/1917 21:45:01") \n"""\
+ """or relative ones with format <+|-><number><s|m|h|d|w|y> (e.g. "-12h").\n"""\
+ """The keyword "now" is also accepted."""
+ self.ui.xEditMin.setToolTip(timetooltip)
+ self.ui.xEditMax.setToolTip(timetooltip)
+ else:
+ # The default settings are ok for non-time plots
+ self.ui.xEditMin.setValidator(Qt.QDoubleValidator(self))
+ self.ui.xEditMax.setValidator(Qt.QDoubleValidator(self))
+ self.ui.xRangeCB.setValidator(Qt.QDoubleValidator(self))
+ self.ui.xRangeCB.addItems(["",
+ "10",
+ "100",
+ "1000",
+ "10000",
+ "100000",
+ "1000000"])
+
+ self.ui.xDynScaleCheckBox.setChecked(self.parent.getXDynScale())
+ auto=self.parent.axisAutoScale(Qwt5.QwtPlot.xBottom)
+ self.ui.xAutoGroupBox.setChecked(not auto)
+
+ self.setXDynScale(self.parent.getXDynScale()) #this call already initialises the edit boxes of the X axis
+ self.ui.xDynScaleCheckBox.setVisible(self.parent.isXDynScaleSupported())
+
+ #Init Y axes groups
+ self._populateYAxisScales()
+ self.ui.y1AutoGroupBox.setChecked(not self.parent.axisAutoScale(Qwt5.QwtPlot.yLeft))
+ self.ui.y2AutoGroupBox.setChecked(not self.parent.axisAutoScale(Qwt5.QwtPlot.yRight))
+
+ #set validators for Y min/max edits
+ self.ui.y1EditMin.setValidator(Qt.QDoubleValidator(self))
+ self.ui.y1EditMax.setValidator(Qt.QDoubleValidator(self))
+ self.ui.y2EditMin.setValidator(Qt.QDoubleValidator(self))
+ self.ui.y2EditMax.setValidator(Qt.QDoubleValidator(self))
+
+ #populate initial axis mode (linear or logarithmic) values from plot. Warning!: we're using
+ #qwt QwtPlot.axis enum type to relate our GUI combo name and qwt axis name (enum type).
+ axes = [self.ui.y1ModeComboBox, self.ui.y2ModeComboBox, self.ui.xModeComboBox]
+ for axis in range(len(axes)):
+ scaleType = self.parent.axisScaleEngine(axis).transformation().type()
+ if scaleType == Qwt5.QwtScaleTransformation.Linear:
+ axes[axis].setCurrentIndex(0)
+ elif scaleType == Qwt5.QwtScaleTransformation.Log10:
+ axes[axis].setCurrentIndex(1)
+ else:
+ raise TypeError, "TaurusPlotConfigDialog::__init__(): unexpected axis scale type (linear or logarihtmic expected)"
+ self.ui.xModeComboBox.setEnabled(not self.parent.getXIsTime())
+
+ #determine which axes are visible
+ if not self.parent.axisEnabled(Qwt5.QwtPlot.xBottom):
+ self.ui.xGroupBox.setVisible(False)
+
+ #populate initial peaks from parent
+ if self.parent._showMaxPeaks and self.parent._showMinPeaks:
+ self.ui.peaksComboBox.setCurrentIndex(0)
+ elif self.parent._showMaxPeaks:
+ self.ui.peaksComboBox.setCurrentIndex(1)
+ elif self.parent._showMinPeaks:
+ self.ui.peaksComboBox.setCurrentIndex(2)
+ else:
+ self.ui.peaksComboBox.setCurrentIndex(3)
+
+ #connect signals
+ self.connect(self.ui.buttonBox.button(Qt.QDialogButtonBox.Close), Qt.SIGNAL("clicked()"), self.hide)
+ self.connect(self.ui.buttonBox.button(Qt.QDialogButtonBox.Apply), Qt.SIGNAL("clicked()"), self.apply)
+ self.connect(self.ui.xAutoGroupBox, Qt.SIGNAL("toggled (bool)"),self.toggledAutoScale)
+ self.connect(self.ui.y1AutoGroupBox, Qt.SIGNAL("toggled (bool)"),self.toggledAutoScale)
+ self.connect(self.ui.y2AutoGroupBox, Qt.SIGNAL("toggled (bool)"),self.toggledAutoScale)
+# self.connect(self.ui.xEditMin, Qt.SIGNAL("returnPressed()"),self.apply)
+# self.connect(self.ui.xEditMax, Qt.SIGNAL("returnPressed()"),self.apply)
+# self.connect(self.ui.y1EditMin, Qt.SIGNAL("returnPressed()"),self.apply)
+# self.connect(self.ui.y1EditMax, Qt.SIGNAL("returnPressed()"),self.apply)
+# self.connect(self.ui.y2EditMin, Qt.SIGNAL("returnPressed()"),self.apply)
+# self.connect(self.ui.y2EditMax, Qt.SIGNAL("returnPressed()"),self.apply)
+ self.connect(self.ui.xModeComboBox, Qt.SIGNAL("currentIndexChanged(const QString&)"),self.modeComboChanged)
+ self.connect(self.ui.xDynScaleCheckBox, Qt.SIGNAL("toggled (bool)"),self.setXDynScale)
+ #self.connect(self.ui.xRangeCB, Qt.SIGNAL("currentIndexChanged(const QString&)"),self.apply)
+ self.connect(self.ui.y1ModeComboBox, Qt.SIGNAL("currentIndexChanged(const QString&)"),self.modeComboChanged)
+ self.connect(self.ui.y2ModeComboBox, Qt.SIGNAL("currentIndexChanged(const QString&)"),self.modeComboChanged)
+ self.connect(self.ui.peaksComboBox, Qt.SIGNAL("currentIndexChanged(int)"),self.peaksComboChanged)
+ #self.connect(self.curvesAppearanceChooser, Qt.SIGNAL("controlChanged"),self.apply) #"autoapply" mode for *all* the curve appearance controls
+ self.connect(self.curvesAppearanceChooser.assignToY1BT, Qt.SIGNAL("clicked()"),self.setCurvesYAxis)
+ self.connect(self.curvesAppearanceChooser.assignToY2BT, Qt.SIGNAL("clicked()"),self.setCurvesYAxis)
+ self.connect(self.curvesAppearanceChooser.bckgndBT, Qt.SIGNAL("clicked()"),self.changeBackgroundColor)
+ self.connect(self.curvesAppearanceChooser.changeTitlesBT, Qt.SIGNAL("clicked()"),self.onChangeTitles)
+ self.connect(self.curvesAppearanceChooser.curvesLW, Qt.SIGNAL("CurveTitleEdited"),self.onCurveTitleEdited)
+
+ #finally adjust size
+ self.adjustSize()
+
+ def _populateXAxisScales(self):
+ xMin = self.parent.axisScaleDiv(Qwt5.QwtPlot.xBottom).lowerBound()
+ xMax = self.parent.axisScaleDiv(Qwt5.QwtPlot.xBottom).upperBound()
+ if self.parent.getXIsTime():
+ self.ui.xEditMin.setText(time.strftime('%Y/%m/%d %H:%M:%S',time.localtime(int(xMin))))
+ self.ui.xEditMax.setText(time.strftime('%Y/%m/%d %H:%M:%S',time.localtime(int(xMax))))
+ else:
+ self.ui.xEditMin.setText(str(xMin))
+ self.ui.xEditMax.setText(str(xMax))
+
+ def _populateYAxisScales(self, axis=None):
+ if axis is None or axis==Qwt5.QwtPlot.yLeft:
+ self.ui.y1EditMin.setText(str(self.parent.axisScaleDiv(Qwt5.QwtPlot.yLeft).lowerBound()))
+ self.ui.y1EditMax.setText(str(self.parent.axisScaleDiv(Qwt5.QwtPlot.yLeft).upperBound()))
+ if axis is None or axis==Qwt5.QwtPlot.yRight:
+ self.ui.y2EditMin.setText(str(self.parent.axisScaleDiv(Qwt5.QwtPlot.yRight).lowerBound()))
+ self.ui.y2EditMax.setText(str(self.parent.axisScaleDiv(Qwt5.QwtPlot.yRight).upperBound()))
+
+ def deltatime2str(self,dt, fuzzy=False):
+ '''converts a time diff in secs to a string.
+ If fuzzy=True it returns an approx time diff in s, min, hours or days'''
+ dt=float(dt)
+ if not fuzzy:return "%g s"%dt
+ if dt<2: return "%3.3g s"%dt
+ elif dt<120 : return "%g s"%round(dt,0)
+ elif dt<7200: return "%g m"%round(dt/60,0)
+ elif dt<172800: return "%g h"%round(dt/3600,0)
+ else: return "%g d"%round(dt/86400,0)
+
+ def str2deltatime(self,strtime):
+ '''Translates a time string to seconds
+ examples of valid relative times are: "now", "NOW", "Now", "-1d", "3w", "- 3.6e3 s",...
+ examples of non-valid relative times:, "now + 2h", "-5", "3H" (unit names are case-sensitive)
+ '''
+ strtime=str(strtime).strip()
+ timeunits={'s':1, 'm':60, 'h':3600, 'd':3600*24, 'w': 3600*24*7, 'y':3600*24*365}
+ if strtime.lower()=="now": return time.time()
+ if strtime[-1] in timeunits.keys():
+ try: return float(strtime[:-1])*timeunits[strtime[-1]]
+ except Exception,e:
+ print '[str2deltatime] No format could be applied to "%s"'%strtime
+ return None
+ else:
+ print '[str2deltatime] Non-supported unit "%s"'%strtime[-1]
+ return None
+
+ def strtime2epoch(self,strtime):
+ '''
+ Translates a str into an epoch value. It accepts "absolute" time notation as well as
+ "relative to current time notation" (by expliciting a "+" or "-" prefix)
+ (see str2deltatime for relative time notation).
+
+ examples of valid absolute times: "2008-3-25 14:21:59", "25/03/08 14:21", "03-25-2008",...
+
+ It returns None if strtime couldn't be interpreted
+ '''
+ import time
+ t=None
+ strtime=str(strtime).strip()
+
+ #try with relative time keywords
+ if strtime[0] in ['+','-']:
+ reltime=self.str2deltatime(strtime)
+ if reltime is not None: return time.time()+reltime
+
+ if strtime.lower()=="now": return time.time()
+
+ #try with absolute time
+ hour_fts = ['%H:%M:%S','%H:%M','']#,"%M'",'%S"'
+ date_fts = ['%Y-%m-%d','%y-%m-%d','%Y/%m/%d','%y/%m/%d','%d-%m-%Y','%d/%m/%Y','%m-%d-%Y','%m/%d/%Y']
+
+ tfs = []
+ for d in date_fts:
+ for h in hour_fts:
+ if h:
+ tfs.append('%s %s'%(d,h))
+ else:
+ tfs.append(d)
+
+ for tf in tfs:
+ try:
+ #print 'trying ',tf
+ t = time.strptime(strtime,tf)
+ if t[0]<1970:
+ lt = time.localtime()
+ # (2008, 9, 23, 15, 44, 24, 1, 267, 1)
+ t = (lt[0],lt[1],lt[2],t[3],t[4],lt[5],lt[6],lt[7],lt[8])
+ break
+ except Exception,e:
+ pass
+ if t:
+ return time.mktime(t)
+ else:
+ print 'No format could be applied to "%s"'%strtime
+ return None
+
+
+ def validate(self):
+ '''validates the inputs in the dialog.
+ If validation is ok, it returns a tuple containing min/max values for each axis (None if they are autoscaled)
+ If validation failed, it returns False.
+
+ .. note::
+ the values of the max/min boxes are already validated thanks to their attached QDoubleValidators
+ (except for xMin/xMax in time Mode, but this case is handled by strtime2epoch)
+ '''
+ xMin=xMax=y1Min=y1Max=y2Min=y2Max=None
+
+ #Validating X axis values
+ xMin=self.parent.axisScaleDiv(Qwt5.QwtPlot.xBottom).lowerBound()
+ xMax=self.parent.axisScaleDiv(Qwt5.QwtPlot.xBottom).upperBound()
+ if self.ui.xDynScaleCheckBox.isChecked():
+ if self.parent.getXIsTime():
+ rg = abs(self.str2deltatime(str(self.ui.xRangeCB.currentText())))
+ ok1= (rg is not None)
+ else:
+ try:
+ rg, ok1 = float(self.ui.xRangeCB.currentText()), True
+ except:
+ rg, ok1 = 0.0, False
+ xMin=xMax-rg
+ if not ok1 or (xMin >= xMax):
+ Qt.QMessageBox.warning(self, "Invalid parameters for X axis range")
+ return False
+ elif self.ui.xAutoGroupBox.isChecked():
+ if self.parent.getXIsTime(): #time mode
+ xMin = self.strtime2epoch(self.ui.xEditMin.text())
+ xMax = self.strtime2epoch(self.ui.xEditMax.text())
+ ok1= (xMin is not None)
+ ok2= (xMax is not None)
+ else: #XY mode
+ try:
+ xMin, ok1 = float(self.ui.xEditMin.text()), True
+ except:
+ xMin, ok1 = 0.0, False
+ try:
+ xMax, ok2 = float(self.ui.xEditMax.text()), True
+ except:
+ xMax, ok2 = 0.0, False
+ if not (ok1 and ok2) or (xMin >= xMax):
+ Qt.QMessageBox.warning(self, "Invalid parameters for X axis",
+ "Min value must be strictly less than max value")
+ return False
+
+ #Validating Y1 axis values
+ if self.ui.y1AutoGroupBox.isChecked():
+ try:
+ y1Min, ok1 = float(self.ui.y1EditMin.text()), True
+ except:
+ y1Min, ok1 = 0.0, False
+ try:
+ y1Max, ok2 = float(self.ui.y1EditMax.text()), True
+ except:
+ y1Max, ok2 = 0.0, False
+ if not(ok1 and ok2) or (y1Min >= y1Max):
+ Qt.QMessageBox.warning(self, "Invalid parameters for Y1 axis",
+ "Min value must be strictly less than max value")
+ return False
+
+ #Validating Y2 axis values
+ if self.ui.y2AutoGroupBox.isChecked():
+ try:
+ y2Min, ok1 = float(self.ui.y2EditMin.text()), True
+ except:
+ y2Min, ok1 = 0.0, False
+ try:
+ y2Max, ok2 = float(self.ui.y2EditMax.text()), True
+ except:
+ y2Max, ok2 = 0.0, False
+ if not (ok1 and ok2) or (y2Min >= y2Max):
+ Qt.QMessageBox.warning(self, "Invalid parameters for Y2 axis",
+ "Min value must be strictly less than max value")
+ return False
+
+ #if we reached this point, the input is valid
+ return (xMin,xMax,y1Min,y1Max,y2Min,y2Max)
+
+ def apply(self):
+ """This will apply the values set in the dialog. Note that some of them
+ are not necessary to be set, since they're already are set when changing the item selected"""
+
+ #Apply the changes from the curves Appearance widget (they are already validated).
+ prop,names=self.curvesAppearanceChooser.onApply()
+ self.parent.onCurveAppearanceChanged(prop,names)
+
+ #validate the rest of the inputs
+ v=self.validate()
+ if not v: return
+ xMin,xMax,y1Min,y1Max,y2Min,y2Max=v
+
+ self.parent.setAxisScale(Qwt5.QwtPlot.xBottom,xMin, xMax)
+ self.parent.setAxisScale(Qwt5.QwtPlot.yLeft, y1Min, y1Max)
+ self.parent.setAxisScale(Qwt5.QwtPlot.yRight, y2Min, y2Max)
+
+ self.parent._xMax,self.parent._xMin=xMax,xMin
+
+ def toggledAutoScale(self, toggled):
+ """This will catch the group boxes check/uncheck event, and will enable autoscale in case
+ the event has been unchecking 'disable autoscale'"""
+ #get and check who fired the signal
+ groupBox = self.sender()
+ if groupBox is None or not isinstance(groupBox, Qt.QGroupBox):
+ self.error("TaurusPlotConfig::toggledAutoScale(): event is not recognized")
+ return
+ #set the axis autoscale in the corresponding axis
+ if groupBox.objectName() == "xAutoGroupBox" and not toggled:
+ self.parent.setAxisAutoScale(Qwt5.QwtPlot.xBottom)
+ elif groupBox.objectName() == "y1AutoGroupBox" and not toggled:
+ self.parent.setAxisAutoScale(Qwt5.QwtPlot.yLeft)
+ elif groupBox.objectName() == "y2AutoGroupBox" and not toggled:
+ self.parent.setAxisAutoScale(Qwt5.QwtPlot.yRight)
+
+ def modeComboChanged(self, itemSelected):
+ """This will catch the combo box selection change and will set the corresponding axis scale to
+ the value passed as parameter"""
+ #get and check who fired the signal
+ comboBox = self.sender()
+ if comboBox is None or not isinstance(comboBox, Qt.QComboBox):
+ self.error("TaurusPlotConfig::modeComboChanged(): event is not recognized")
+ return
+ else:
+ #set the scale for the corresponding axis
+ if comboBox.objectName() == "xModeComboBox":
+ if not self.parent.getXIsTime():
+ self.parent.setAxisScaleType(Qwt5.QwtPlot.xBottom,itemSelected)
+ elif comboBox.objectName() == "y1ModeComboBox":
+ self.parent.setAxisScaleType(Qwt5.QwtPlot.yLeft,itemSelected)
+ elif comboBox.objectName() == "y2ModeComboBox":
+ self.parent.setAxisScaleType(Qwt5.QwtPlot.yRight,itemSelected)
+ else:
+ self.error("TaurusPlotConfig::modeComboChanged() invalid axis: " + comboBox.objectName())
+
+ def setXDynScale(self,checked):
+ if checked:
+ if self.parent.getXIsTime(): rg=self.deltatime2str(self.parent.getXAxisRange(),fuzzy=True)
+ else: rg="%g"%self.parent.getXAxisRange()
+ self.ui.xRangeCB.setEditText(rg)
+ self.ui.xAutoGroupBox.setChecked(True) #disable autoscale for the X axis
+ else:
+ self._populateXAxisScales()
+ self.parent.setXDynScale(checked)
+
+ def peaksComboChanged(self, itemSelected):
+ """This will catch the combo box selection change and will set the corresponding axis to
+ show peaks"""
+ if itemSelected == 0:
+ maxPeak = minPeak = True
+ elif itemSelected == 1:
+ maxPeak = True
+ minPeak = False
+ elif itemSelected == 2:
+ maxPeak = False
+ minPeak = True
+ else:
+ maxPeak = minPeak = False
+ self.parent.showMaxPeaks(maxPeak)
+ self.parent.showMinPeaks(minPeak)
+
+ def showCalendar(self,target):
+ return
+ self.qcalendar = Qt.QCalendarWidget()
+ self.qcalendar.show()
+
+ def setCurvesYAxis(self, curvesNamesList=None, axis=None):
+ """ calls the parent's setCurvesYAxis method but it automatically determines the parameters if not given"""
+ if curvesNamesList is None:
+ curvesNamesList = self.curvesAppearanceChooser.getSelectedCurveNames()
+ if axis is None:
+ sender=self.sender()
+ if sender is self.curvesAppearanceChooser.assignToY1BT:
+ axis=Qwt5.QwtPlot.yLeft
+ elif sender is self.curvesAppearanceChooser.assignToY2BT:
+ axis=Qwt5.QwtPlot.yRight
+ else:
+ raise ValueError("Cannot determine axis from %s"%sender)
+ #call the parent's setCurvesYAxis()
+ self.parent.setCurvesYAxis(curvesNamesList,axis)
+ #update the axis scale edits
+ self._populateYAxisScales(axis)
+
+ def changeBackgroundColor(self):
+ """Launches a dialog for choosing the parent's canvas background color"""
+ plot = self.parent
+ color = Qt.QColorDialog.getColor(plot.canvasBackground (), self)
+ if Qt.QColor.isValid(color):
+ plot.setCanvasBackground(color)
+ plot.replot()
+
+ def onChangeTitles(self):
+ '''Calls The parent's changeCurvesTitlesDialog method, with the selected
+ curves list as the parameter
+ '''
+ curveNamesList = self.curvesAppearanceChooser.getSelectedCurveNames()
+ newTitlesDict = self.parent.changeCurvesTitlesDialog(curveNamesList=curveNamesList)
+ self.curvesAppearanceChooser.updateTitles(newTitlesDict)
+
+ def onCurveTitleEdited(self, name, newTitle):
+ '''slot used when a curve title is edited
+
+ :param name: (str) curve name
+ :param name: (QString) new title
+ '''
+ newTitlesDict = self.parent.setCurvesTitle(newTitle, [name])
+ self.curvesAppearanceChooser.updateTitles(newTitlesDict)