Beispiel #1
0
    def setModel(self, modelNames):
        '''Removes current TaurusCurveItems and adds new ones.

        :param modelNames: (sequence<str> or str) the names of the models to be
                           plotted. For convenience, a string is also accepted
                           (instead of a sequence of strings), in which case the
                           string will be internally converted to a sequence by
                           splitting it on whitespace and commas. Each model can
                           optionally be composed of two parts, separated by "|"
                           indicating X and Y components for the curve. If only
                           one part is given, it is used for Y and X is
                           automatically generated as an index.

        .. seealso:: :meth:`addModels`
        '''

        plot = self.get_plot()
        # delete current TaurusCurveItems
        taurusCurveItems = [
            item for item in plot.get_public_items()
            if isinstance(item, TaurusCurveItem)
        ]
        plot.del_items(taurusCurveItems)
        self._modelNames = CaselessList()
        # add new TaurusCurveItems
        self.addModels(modelNames)
Beispiel #2
0
 def __init__(self,
              parent=None,
              designMode=False,
              taurusparam=None,
              toolbar=True,
              **kwargs):
     '''see :class:`guiqwt.plot.CurveDialog` for other valid initialization parameters'''
     CurveDialog.__init__(self, parent=parent, toolbar=toolbar, **kwargs)
     TaurusBaseWidget.__init__(self, 'TaurusTrendDialog')
     self.deprecated(rel='4.1',
                     dep='TaurusTrendDialog',
                     alt='TaurusTrend / taurus tpg trend launcher')
     self.setWindowFlags(Qt.Qt.Widget)
     self._designMode = designMode
     self._modelNames = CaselessList()
     from guiqwt.styles import style_generator
     self.style = style_generator()
     self.setSupportedMimeTypes(
         [TAURUS_MODEL_LIST_MIME_TYPE, TAURUS_ATTR_MIME_TYPE])
     from taurus.qt.qtgui.extra_guiqwt.tools import TaurusModelChooserTool, AutoScrollTool
     self.add_tool(TaurusModelChooserTool, singleModel=False)
     self.add_tool(AutoScrollTool)
     self.setModifiableByUser(self._modifiableByUser)
     if taurusparam is None:
         taurusparam = TaurusTrendParam()
     self.defaultTaurusparam = taurusparam
     self.setContextMenuPolicy(Qt.Qt.CustomContextMenu)
     self.registerConfigDelegate(self.get_tool(AutoScrollTool))
Beispiel #3
0
 def addModels(self, models):
     ''' Add given models to the selected models list'''
     if len(models) == 0:
         models = ['']
     if self.isSingleModelMode():
         self.resetListedModels()
     if self._allowDuplicates:
         self.list.addModels(models)
     else:
         listedmodels = CaselessList(self.getListedModels())
         for m in models:
             if m not in listedmodels:
                 listedmodels.append(m)
                 self.list.addModels([m])
Beispiel #4
0
 def addModels(self, models):
     ''' Add given models to the selected models list'''
     if len(models) == 0:
         models = ['']
     if self.isSingleModelMode():
         self.resetListedModels()
     if self._allowDuplicates:
         self.list.addModels(models)
     else:
         listedmodels = CaselessList(self.getListedModels())
         for m in models:
             if m not in listedmodels:
                 listedmodels.append(m)
                 self.list.addModels([m])
Beispiel #5
0
 def __init__(self, parent=None, designMode=False, toolbar=True, **kwargs):
     '''see :class:`guiqwt.plot.CurveDialog` for other valid initialization parameters'''
     CurveDialog.__init__(self, parent=parent, toolbar=toolbar, **kwargs)
     TaurusBaseWidget.__init__(self, 'TaurusCurveDialog')
     self.setWindowFlags(Qt.Qt.Widget)
     self._designMode = designMode
     self._modelNames = CaselessList()
     from guiqwt.styles import style_generator
     self.style = style_generator()
     self.setSupportedMimeTypes(
         [TAURUS_MODEL_LIST_MIME_TYPE, TAURUS_ATTR_MIME_TYPE])
     from taurus.qt.qtgui.extra_guiqwt.tools import TaurusCurveChooserTool
     self.add_tool(TaurusCurveChooserTool)
     self.setModifiableByUser(self._modifiableByUser)
     self.setContextMenuPolicy(Qt.Qt.CustomContextMenu)
Beispiel #6
0
    def setModel(self, modelNames):
        '''Removes current TaurusCurveItems and adds new ones.

        :param modelNames: (sequence<str> or str) the names of the models to be
                           plotted. For convenience, a string is also accepted
                           (instead of a sequence of strings), in which case the
                           string will be internally converted to a sequence by
                           splitting it on whitespace and commas.

        .. seealso:: :meth:`addModels`
        '''

        plot = self.get_plot()
        # delete current TaurusCurveItems
        taurusTrendItems = self.getTaurusTrendItems()
        plot.del_items(taurusTrendItems)
        self._modelNames = CaselessList()
        # add new TaurusCurveItems
        self.addModels(modelNames)
Beispiel #7
0
 def __init__(self, stream, cols=None, number_fmt='%8.4f', col_width=8,
              col_sep='  ', output_block=False, **pars):
     DataRecorder.__init__(self, **pars)
     self._stream = weakref.ref(stream)
     if not number_fmt.startswith('%'):
         number_fmt = '%%s' % number_fmt
     self._number_fmt = number_fmt
     self._col_sep = col_sep
     self._col_width = col_width
     if isinstance(cols, collections.Sequence) and \
             not isinstance(cols, str):
         cols = CaselessList(cols)
     elif isinstance(cols, numbers.Number):
         cols = cols
     else:
         cols = None
     self._columns = cols
     self._output_block = output_block
Beispiel #8
0
 def __init__(self, stream, cols=None, number_fmt='%8.4f', col_width=8,
              col_sep='  ', output_block=False, **pars):
     DataRecorder.__init__(self, **pars)
     self._stream = stream
     if not number_fmt.startswith('%'):
         number_fmt = '%%s' % number_fmt
     self._number_fmt = number_fmt
     self._col_sep = col_sep
     self._col_width = col_width
     if operator.isSequenceType(cols) and \
             not isinstance(cols, (str, unicode)):
         cols = CaselessList(cols)
     elif operator.isNumberType(cols):
         cols = cols
     else:
         cols = None
     self._columns = cols
     self._output_block = output_block
Beispiel #9
0
class TaurusCurveDialog(CurveDialog, TaurusBaseWidget):
    '''A taurus dialog for showing 1D data.
    It behaves as a regular :class:`guiqwt.plot.CurveDialog` but it also offers
    the expected Taurus interface (e.g. setting models, save/apply configs,
    drag&drops,...)

    .. seealso:: :class:`TaurusCurveWidget`
    '''
    _modifiableByUser = True
    modelChanged = Qt.pyqtSignal([], ['QStringList'], ['QString'])

    def __init__(self, parent=None, designMode=False, toolbar=True, **kwargs):
        '''see :class:`guiqwt.plot.CurveDialog` for other valid initialization parameters'''
        CurveDialog.__init__(self, parent=parent, toolbar=toolbar, **kwargs)
        TaurusBaseWidget.__init__(self, 'TaurusCurveDialog')
        self.deprecated(rel='4.1',
                        dep='TaurusCurveDialog',
                        alt='TaurusPlot / taurus tpg plot launcher')
        self.setWindowFlags(Qt.Qt.Widget)
        self._designMode = designMode
        self._modelNames = CaselessList()
        from guiqwt.styles import style_generator
        self.style = style_generator()
        self.setSupportedMimeTypes(
            [TAURUS_MODEL_LIST_MIME_TYPE, TAURUS_ATTR_MIME_TYPE])
        from taurus.qt.qtgui.extra_guiqwt.tools import TaurusCurveChooserTool
        self.add_tool(TaurusCurveChooserTool)
        self.setModifiableByUser(self._modifiableByUser)
        self.setContextMenuPolicy(Qt.Qt.CustomContextMenu)

    def keyPressEvent(self, event):
        if (event.key() == Qt.Qt.Key_Escape):
            event.ignore()
        else:
            ImageDialog.keyPressEvent(self, event)

    def getModelClass(self):
        '''reimplemented from :class:`TaurusBaseWidget`'''
        return taurus.core.taurusattribute.TaurusAttribute

    def _splitModel(self, modelNames):
        '''convert str to list if needed (commas and whitespace are considered as separators)'''
        if isinstance(modelNames, string_types):
            modelNames = str(modelNames).replace(',', ' ')
            modelNames = modelNames.split()
        return modelNames

    @Qt.pyqtSlot('QStringList')
    def setModel(self, modelNames):
        '''Removes current TaurusCurveItems and adds new ones.

        :param modelNames: (sequence<str> or str) the names of the models to be
                           plotted. For convenience, a string is also accepted
                           (instead of a sequence of strings), in which case the
                           string will be internally converted to a sequence by
                           splitting it on whitespace and commas. Each model can
                           optionally be composed of two parts, separated by "|"
                           indicating X and Y components for the curve. If only
                           one part is given, it is used for Y and X is
                           automatically generated as an index.

        .. seealso:: :meth:`addModels`
        '''

        plot = self.get_plot()
        # delete current TaurusCurveItems
        taurusCurveItems = [
            item for item in plot.get_public_items()
            if isinstance(item, TaurusCurveItem)
        ]
        plot.del_items(taurusCurveItems)
        self._modelNames = CaselessList()
        # add new TaurusCurveItems
        self.addModels(modelNames)

    def addModels(self, modelNames):
        '''Creates TaurusCurveItems (one for each model in modelNames) and attaches
        them to the plot.

        .. note:: you can also add curves using :meth:`add_items`. :meth:`addModels`
                  is only a more Taurus-oriented interface. :meth:`add_items`
                  gives you more control.

        :param modelNames: (sequence<str> or str) the names of the models to be
                           plotted. For convenience, string is also accepted
                           (instead of a sequence of strings), in which case the
                           string will be internally converted to a sequence by
                           splitting it on whitespace and commas. Each model can
                           optionally be composed of two parts, separated by "|"
                           indicating X and Y components for the curve. If only
                           one part is given, it is used for Y and X is
                           automatically generated as an index.

        .. seealso:: :meth:`add_item`
        '''
        plot = self.get_plot()

        # pre-process the model names
        modelNames = self._splitModel(modelNames)
        self._modelNames.extend([str(n) for n in modelNames])
        if self._designMode:
            return
        # create and attach new TaurusCurveItems
        for m in modelNames:
            # split model into x and y components
            mx_my = m.split('|')
            n = len(mx_my)
            if n == 1:
                mx, my = None, mx_my[0]
            elif n == 2:
                mx, my = mx_my
            else:
                self.warning('Invalid model "%s" (Skipping)' % mx_my)
            # cycle styles
            style = next(self.style)
            color = style[0]
            linestyle = style[1:]
            # add the item
            item = make.curve(mx,
                              my,
                              color=color,
                              linestyle=linestyle,
                              linewidth=2)
            item.set_readonly(not self.isModifiableByUser())
            plot.add_item(item)
        self.modelChanged.emit()

    def getModel(self):
        """reimplemented from :class:`TaurusBaseWidget`"""
        return self._modelNames

    def setModifiableByUser(self, modifiable):
        """reimplemented from :class:`TaurusBaseWidget`"""
        from taurus.qt.qtgui.extra_guiqwt.tools import TaurusCurveChooserTool
        self.get_tool(TaurusCurveChooserTool).action.setEnabled(modifiable)
        self.get_plot().set_items_readonly(not modifiable)
        TaurusBaseWidget.setModifiableByUser(self, modifiable)

    @classmethod
    def getQtDesignerPluginInfo(cls):
        """reimplemented from :class:`TaurusBaseWidget`"""
        ret = TaurusBaseWidget.getQtDesignerPluginInfo()
        ret['module'] = 'taurus.qt.qtgui.extra_guiqwt'
        ret['group'] = 'Taurus Display'
        ret['icon'] = 'designer:qwtplot.png'
        return ret

    model = Qt.pyqtProperty("QStringList", getModel, setModel,
                            TaurusBaseWidget.resetModel)
    modifiableByUser = Qt.pyqtProperty("bool",
                                       TaurusBaseWidget.isModifiableByUser,
                                       setModifiableByUser,
                                       TaurusBaseWidget.resetModifiableByUser)
Beispiel #10
0
class TaurusTrendDialog(CurveDialog, TaurusBaseWidget):
    '''A taurus widget for showing trends of scalar data.
    It is an specialization of :class:`guiqwt.plot.CurveWidget`, for displaying
    trends and offering the expected Taurus interface (e.g. setting models,
    save/apply configs, drag&drops,...)

    .. seealso:: :class:`TaurusTrendDialog`
    '''
    _modifiableByUser = True

    modelChanged = Qt.pyqtSignal([], ['QStringList'], ['QString'])

    def __init__(self,
                 parent=None,
                 designMode=False,
                 taurusparam=None,
                 toolbar=True,
                 **kwargs):
        '''see :class:`guiqwt.plot.CurveDialog` for other valid initialization parameters'''
        CurveDialog.__init__(self, parent=parent, toolbar=toolbar, **kwargs)
        TaurusBaseWidget.__init__(self, 'TaurusTrendDialog')
        self.deprecated(rel='4.1',
                        dep='TaurusTrendDialog',
                        alt='TaurusTrend / taurus tpg trend launcher')
        self.setWindowFlags(Qt.Qt.Widget)
        self._designMode = designMode
        self._modelNames = CaselessList()
        from guiqwt.styles import style_generator
        self.style = style_generator()
        self.setSupportedMimeTypes(
            [TAURUS_MODEL_LIST_MIME_TYPE, TAURUS_ATTR_MIME_TYPE])
        from taurus.qt.qtgui.extra_guiqwt.tools import TaurusModelChooserTool, AutoScrollTool
        self.add_tool(TaurusModelChooserTool, singleModel=False)
        self.add_tool(AutoScrollTool)
        self.setModifiableByUser(self._modifiableByUser)
        if taurusparam is None:
            taurusparam = TaurusTrendParam()
        self.defaultTaurusparam = taurusparam
        self.setContextMenuPolicy(Qt.Qt.CustomContextMenu)
        self.registerConfigDelegate(self.get_tool(AutoScrollTool))

    def keyPressEvent(self, event):
        if (event.key() == Qt.Qt.Key_Escape):
            event.ignore()
        else:
            ImageDialog.keyPressEvent(self, event)

    def getModelClass(self):
        '''reimplemented from :class:`TaurusBaseWidget`'''
        return taurus.core.taurusattribute.TaurusAttribute

    def getTaurusTrendItems(self):
        return [
            item for item in self.get_plot().get_public_items()
            if isinstance(item, TaurusTrendItem)
        ]

    def _splitModel(self, modelNames):
        '''convert str to list if needed (commas and whitespace are considered as separators)'''
        if isinstance(modelNames, string_types):
            modelNames = str(modelNames).replace(',', ' ')
            modelNames = modelNames.split()
        return modelNames

    @Qt.pyqtSlot('QStringList')
    def setModel(self, modelNames):
        '''Removes current TaurusCurveItems and adds new ones.

        :param modelNames: (sequence<str> or str) the names of the models to be
                           plotted. For convenience, a string is also accepted
                           (instead of a sequence of strings), in which case the
                           string will be internally converted to a sequence by
                           splitting it on whitespace and commas.

        .. seealso:: :meth:`addModels`
        '''

        plot = self.get_plot()
        # delete current TaurusCurveItems
        taurusTrendItems = self.getTaurusTrendItems()
        plot.del_items(taurusTrendItems)
        self._modelNames = CaselessList()
        # add new TaurusCurveItems
        self.addModels(modelNames)

    def addModels(self, modelNames):
        '''Creates TaurusCurveItems (one for each model in modelNames) and attaches
        them to the plot.

        .. note:: you can also add curves using :meth:`add_items`. :meth:`addModels`
                  is only a more Taurus-oriented interface. :meth:`add_items`
                  gives you more control.

        :param modelNames: (sequence<str> or str) the names of the models to be
                           plotted. For convenience, a string is also accepted
                           (instead of a sequence of strings), in which case the
                           string will be internally converted to a sequence by
                           splitting it on whitespace and commas.

        .. seealso:: :meth:`add_item`
        '''
        plot = self.get_plot()

        # pre-process the model names
        modelNames = self._splitModel(modelNames)
        self._modelNames.extend([str(n) for n in modelNames])
        if self._designMode:
            return
        # create and attach new TaurusCurveItems
        for m in modelNames:
            # cycle styles
            style = next(self.style)
            # add the item
            item = make.ttrend(m,
                               color=style[0],
                               linestyle=style[1:],
                               linewidth=2,
                               taurusparam=copy.deepcopy(
                                   self.defaultTaurusparam))
            item.set_readonly(not self.isModifiableByUser())
            plot.add_item(item)
            item.update_params()

        self.setStackMode(self.defaultTaurusparam.stackMode)
        self.modelChanged.emit()

    def getModel(self):
        """reimplemented from :class:`TaurusBaseWidget`"""
        return self._modelNames

    def setUseArchiving(self, enable):
        '''enables/disables looking up in the archiver for data stored before
        the Trend was started

        :param enable: (bool) if True, archiving values will be used if available
        '''
        if not self.defaultTaurusparam.stackMode == 'datetime':
            self.info('ignoring setUseArchiving. Reason: not in X time scale')
        self.defaultTaurusparam.useArchiving = enable

    def getUseArchiving(self):
        '''whether TaurusTrend is looking for data in the archiver when needed

        :return: (bool)

        .. seealso:: :meth:`setUseArchiving`
        '''
        return self.defaultTaurusparam.useArchiving

    def resetUseArchiving(self):
        '''Same as setUseArchiving(False)'''
        self.setUseArchiving(False)

    def setMaxDataBufferSize(self, maxSize):
        '''sets the maximum number of events that will be stacked

        :param maxSize: (int) the maximum limit

        .. seealso:: :class:`TaurusTrendSet`
        '''
        for item in self.getTaurusTrendItems():
            item.setBufferSize(maxSize)

        self.defaultTaurusparam.maxBufferSize = maxSize

    def getMaxDataBufferSize(self):
        '''returns the maximum number of events that can be plotted in the trend

        :return: (int)
        '''
        return self.defaultTaurusparam.maxBufferSize

    def resetMaxDataBufferSize(self):
        '''Same as setMaxDataBufferSize(16384)'''
        self.setMaxDataBufferSize(16384)

    def setStackMode(self, mode):
        '''set the type of stack to be used. This determines how X values are
        interpreted:

            - as timestamps ('datetime')
            - as time deltas ('timedelta')
            - as event numbers ('event')

        :param mode:(one of 'datetime', 'timedelta' or 'event')
        '''
        from taurus.qt.qtgui.extra_guiqwt.tools import TimeAxisTool
        mode = str(mode)
        if mode == 'datetime':
            timetool = self.get_tool(TimeAxisTool)
            if timetool is None:
                self.add_tool(TimeAxisTool)
                timetool = self.get_tool(TimeAxisTool)
            timetool.set_scale_y_t(True)
        elif mode == 'deltatime':
            from taurus.qt.qtgui.extra_guiqwt.scales import DeltaTimeScaleEngine
            plot = self.get_plot()
            DeltaTimeScaleEngine.enableInAxis(plot, plot.xBottom, rotation=-45)
        elif mode == 'event':
            plot = self.get_plot()
            scaleEngine = plot.axisScaleEngine(plot.xBottom)
            if hasattr(scaleEngine, 'disableInAxis'):
                scaleEngine.disableInAxis(plot, plot.xBottom)
        else:
            self.error('Unknown stack mode "%s"' % repr(mode))
            return

        self.defaultTaurusparam.stackMode = mode

        for item in self.getTaurusTrendItems():
            item.taurusparam.stackMode = mode

    def getStackMode(self):
        return self.defaultTaurusparam.stackMode

    def resetStackMode(self):
        self.setStackMode('datetime')

    def setModifiableByUser(self, modifiable):
        """reimplemented from :class:`TaurusBaseWidget`"""
        from taurus.qt.qtgui.extra_guiqwt.tools import TaurusModelChooserTool
        self.get_tool(TaurusModelChooserTool).action.setEnabled(modifiable)
        self.get_plot().set_items_readonly(not modifiable)
        TaurusBaseWidget.setModifiableByUser(self, modifiable)

    def getDropEventCallback(self):
        """reimplemented from :class:`TaurusBaseWidget`"""
        return self.addModels

    @classmethod
    def getQtDesignerPluginInfo(cls):
        """reimplemented from :class:`TaurusBaseWidget`"""
        ret = TaurusBaseWidget.getQtDesignerPluginInfo()
        ret['module'] = 'taurus.qt.qtgui.extra_guiqwt'
        ret['group'] = 'Taurus Display'
        ret['icon'] = 'designer:qwtplot.png'
        return ret

    model = Qt.pyqtProperty("QStringList", getModel, setModel,
                            TaurusBaseWidget.resetModel)
    useArchiving = Qt.pyqtProperty("bool", getUseArchiving, setUseArchiving,
                                   resetUseArchiving)
    maxDataBufferSize = Qt.pyqtProperty("int", getMaxDataBufferSize,
                                        setMaxDataBufferSize,
                                        resetMaxDataBufferSize)
    stackMode = Qt.pyqtProperty("QString", getStackMode, setStackMode,
                                resetStackMode)
    modifiableByUser = Qt.pyqtProperty("bool",
                                       TaurusBaseWidget.isModifiableByUser,
                                       setModifiableByUser,
                                       TaurusBaseWidget.resetModifiableByUser)
Beispiel #11
0
    def onExpConfChanged(self, expconf):
        '''
        Slot to be called when experimental configuration changes. It should
        remove the temporary panels and create the new ones needed.

        :param expconf: (dict) An Experiment Description dictionary. See
                        :meth:`sardana.taurus.qt.qtcore.tango.sardana.
                        QDoor.getExperimentDescription`
                        for more details
        '''
        if expconf['ActiveMntGrp'] is None:
            return
        if expconf['ActiveMntGrp'] not in expconf['MntGrpConfigs'].keys():
            self.warning("ActiveMntGrp '%s' is not defined" %
                         expconf['ActiveMntGrp'])
            return
        mgconfig = expconf['MntGrpConfigs'][expconf['ActiveMntGrp']]
        channels = dict(getChannelConfigs(mgconfig, sort=False))

        # classify by type of plot:
        trends1d = {}
        trends2d = {}
        plots1d = {}
        images = {}

        for chname, chdata in channels.items():
            ptype = chdata['plot_type']
            if ptype == PlotType.No:
                continue
            elif ptype == PlotType.Spectrum:
                axes = tuple(chdata['plot_axes'])
                # TODO: get default value from the channel.
                ndim = chdata.get('ndim', 0)
                if ndim == 0:  # this is a trend
                    if axes in trends1d:
                        trends1d[axes].append(chname)
                    else:
                        trends1d[axes] = CaselessList([chname])
                elif ndim == 1:  # a 1D plot (e.g. a spectrum)
                    pass  # TODO: implement
                else:
                    self.warning('Cannot create plot for %s', chname)

            elif ptype == PlotType.Image:
                axes = tuple(chdata['plot_axes'])
                # TODO: get default value from the channel.
                ndim = chdata.get('ndim', 1)
                if ndim == 0:  # a mesh-like plot?
                    pass  # TODO implement
                elif ndim == 1:  # a 2D trend
                    if axes in trends2d:
                        trends2d[axes].append(chname)
                    else:
                        trends2d[axes] = CaselessList([chname])
                elif ndim == 2:  # a 2D plot (e.g. an image)
                    pass  # TODO: implement
                else:
                    self.warning('Cannot create plot for %s', chname)

        new1d, removed1d = self._updateTemporaryTrends1D(trends1d)
        self.newShortMessage.emit("Changed panels (%i new, %i removed)" %
                                  (len(new1d), len(removed1d)))
Beispiel #12
0
 def setImageAttrName(self, attr_name):
     self._image_attr_names = CaselessList()
     self.addImageAttrName(attr_name)