示例#1
0
def _chek_tauruslabel(
    qtbot,
    caplog,
    taurus_test_ds,
    model,
    fmt=None,
    fgRole=None,
    bgRole=None,
    modelIndex=None,
    depr=0,
    expected_fg=None,
    expected_bg=None,
):
    """Check the label foreground and background"""
    # TODO: these tests are not properly isolated. For example, the
    #       parameterization testing fgrole="quality" fails in PySide2
    #       if it is called after another parameterization.
    if expected_fg is None and expected_bg is None:
        raise ValueError("expected_fg or expected_bg must not be None")
    with check_taurus_deprecations(caplog, expected=depr):
        w = TaurusLabel()
        qtbot.addWidget(w)
        if model.startswith("/"):
            model = "tango:{}{}".format(taurus_test_ds, model)
        with qtbot.waitSignal(w.modelChanged, timeout=3200):
            w.setModel(model)
        if fmt is not None:
            w.setFormat(fmt)
        if modelIndex is not None:
            w.setModelIndex(modelIndex)
        if fgRole is not None:
            w.setFgRole(fgRole)
        if bgRole is not None:
            w.setBgRole(bgRole)

        def _ok():
            """Check text"""
            if expected_fg is not None:
                assert w.text() == expected_fg
            if expected_bg is not None:
                p = w.palette()
                assert p.color(p.Background).getRgb()[:3] == expected_bg

        qtbot.waitUntil(_ok, timeout=3200)
示例#2
0
class TaurusValuesTable(TaurusWidget):
    '''
    A table for displaying and/or editing 1D/2D Taurus attributes
    '''
    _showQuality = False
    _writeMode = False

    def __init__(self, parent=None, designMode=False, defaultWriteMode=None):
        TaurusWidget.__init__(self, parent=parent, designMode=designMode)
        self._tableView = TaurusValuesIOTable(self)
        l = Qt.QGridLayout()
        l.addWidget(self._tableView, 1, 0)
        self._tableView.itemDelegate().editorCreated.connect(
            self._onEditorCreated)

        if defaultWriteMode is None:
            self.defaultWriteMode = "rw"
        else:
            self.defaultWriteMode = defaultWriteMode

        self._label = TaurusLabel()
        self._label.setBgRole('quality')
        self._label.setFgRole('quality')

        self._units = Qt.QComboBox()

        self._applyBT = Qt.QPushButton('Apply')
        self._cancelBT = Qt.QPushButton('Cancel')
        self._applyBT.clicked.connect(self.okClicked)
        self._cancelBT.clicked.connect(self.cancelClicked)

        self._rwModeCB = Qt.QCheckBox()
        self._rwModeCB.setText('Write mode')
        self._rwModeCB.toggled.connect(self.setWriteMode)

        lv = Qt.QHBoxLayout()
        lv.addWidget(self._label)
        lv.addWidget(self._units)
        l.addLayout(lv, 2, 0)
        l.addWidget(self._rwModeCB, 0, 0)
        lv = Qt.QHBoxLayout()
        lv.addWidget(self._applyBT)
        lv.addWidget(self._cancelBT)
        l.addLayout(lv, 3, 0)
        self._writeMode = False
        self.setLayout(l)
        self._initActions()

    def _initActions(self):
        """Initializes the actions for this widget (currently, the pause action.)
        """
        self._pauseAction = Qt.QAction("&Pause", self)
        self._pauseAction.setShortcuts([Qt.Qt.Key_P, Qt.Qt.Key_Pause])
        self._pauseAction.setCheckable(True)
        self._pauseAction.setChecked(False)
        self.addAction(self._pauseAction)
        self._pauseAction.toggled.connect(self.setPaused)
        self.chooseModelAction = Qt.QAction("Choose &Model", self)
        self.chooseModelAction.setEnabled(self.isModifiableByUser())
        self.addAction(self.chooseModelAction)
        self.chooseModelAction.triggered[()].connect(self.chooseModel)

    def getModelClass(self):
        '''see :meth:`TaurusWidget.getModelClass`'''
        return taurus.core.taurusattribute.TaurusAttribute

    def setModel(self, model):
        '''Reimplemented from :meth:`TaurusWidget.setModel`'''
        TaurusWidget.setModel(self, model)
        model_obj = self.getModelObj()

        if model_obj.isWritable() and self.defaultWriteMode != "r":
            self._writeMode = True
        else:
            self.defaultWriteMode = "r"

        if model_obj is not None:
            self._tableView._attr = model_obj
            if model_obj.type in [DataType.Integer, DataType.Float]:
                if self._writeMode:
                    try:
                        default_unit = str(model_obj.wvalue.units)
                    except AttributeError:
                        default_unit = ''
                else:
                    default_unit = str(model_obj.rvalue.units)
                # TODO: fill the combobox with the compatible units
                self._units.addItem("%s" % default_unit)
                self._units.setCurrentIndex(self._units.findText(default_unit))
                self._units.setEnabled(False)
            else:
                self._units.setVisible(False)
            raiseException = False
            if model_obj.data_format == DataFormat._2D:
                try:
                    dim_x, dim_y = numpy.shape(model_obj.rvalue)
                except ValueError:
                    raiseException = True
            elif model_obj.data_format == DataFormat._1D:
                try:
                    dim_x, dim_y = len(model_obj.rvalue), 1
                except ValueError:
                    raiseException = True
            else:
                raiseException = True
            if raiseException:
                raise Exception('rvalue is invalid')
            self._tableView.setModel([dim_x, dim_y])
        self.setWriteMode(self._writeMode)
        self._label.setModel(model)

    def handleEvent(self, evt_src, evt_type, evt_value):
        '''see :meth:`TaurusWidget.handleEvent`'''
        #@fixme: in some situations, we may miss some config event because of the qmodel not being set. The whole handleEvent Method and setModel method should be re-thought
        model = self._tableView.model()
        if model is None:
            return
        if evt_type in (TaurusEventType.Change,
                        TaurusEventType.Periodic)\
                and evt_value is not None:
            attr = self.getModelObj()
            model.setAttr(attr)
            model.setWriteMode(self._writeMode)

            hh = self._tableView.horizontalHeader()
            hh.setSectionResizeMode(Qt.QHeaderView.Fixed)
            vh = self._tableView.verticalHeader()
            vh.setSectionResizeMode(Qt.QHeaderView.Fixed)
            if self.defaultWriteMode == "r":
                isWritable = False
            else:
                isWritable = True
            writable = isWritable and self._writeMode and\
                attr.isWritable()
            self.setWriteMode(writable)
        elif evt_type == TaurusEventType.Config:
            # force a read to set an attr
            attr = self.getModelObj()
            model.setAttr(attr)

    def contextMenuEvent(self, event):
        '''Reimplemented from :meth:`QWidget.contextMenuEvent`'''
        menu = Qt.QMenu()
        globalPos = event.globalPos()
        menu.addAction(self.chooseModelAction)
        menu.addAction(self._pauseAction)
        if self._writeMode:
            index = self._tableView.selectedIndexes()[0]
            if index.isValid():
                val = self._tableView.model().getReadValue(index)
                if self._tableView.model().getModifiedDict().has_key(
                    (index.row(), index.column())):
                    menu.addAction(Qt.QIcon.fromTheme('edit-undo'),
                                   "Reset to original value (%s) " % repr(val),
                                   self._tableView.removeChange)
                    menu.addSeparator()
                menu.addAction(Qt.QIcon.fromTheme('process-stop'),
                               "Reset all table", self.askCancel)
                menu.addSeparator()
                menu.addAction(Qt.QIcon.fromTheme('help-browser'), "Help",
                               self._tableView.showHelp)
        menu.exec_(globalPos)
        event.accept()

    def applyChanges(self):
        '''
        Writes table modifications to the device server.
        '''
        tab = self._tableView.model().getModifiedWriteData()
        attr = self.getModelObj()
        if attr.type == DataType.String:
            # String arrays has to be converted to a list
            tab = tab.tolist()
        attr.write(tab)
        self._tableView.model().clearChanges()

    def okClicked(self):
        """This is a SLOT that is being triggered when ACCEPT button is clicked.

        .. note:: This SLOT is called, when user wants to apply table modifications.
                  When no cell was modified it will not be called. When
                  modifications have been done, they will be writen to w_value
                  of an attribute.
        """
        if self._tableView.model().isDirty():
            self.applyChanges()
            self.resetWriteMode()

    def cancelClicked(self):
        """This is a SLOT that is being triggered when CANCEL button is clicked.

        .. note:: This SLOT is called, when user does not want to apply table
                  modifications. When no cell was modified it will not be called.
        """
        if self._tableView.model().isDirty():
            self.askCancel()

    def askCancel(self):
        '''
        Shows a QMessageBox, asking if user wants to cancel all changes. Triggered when user clicks Cancel button.
        '''
        result = Qt.QMessageBox.warning(
            self, 'Your changes will be lost!',
            'Do you want to cancel changes done to the whole table?',
            Qt.QMessageBox.Ok | Qt.QMessageBox.Cancel)
        if result == Qt.QMessageBox.Ok:
            self._tableView.cancelChanges()
            self.resetWriteMode()

    def _onEditorCreated(self):
        '''slot called when an editor has been created'''
        self.setWriteMode(self._writeMode)

    def getWriteMode(self):
        '''whether the widget is showing the read or write values

        :return: (bool)'''
        return self._writeMode

    def setWriteMode(self, isWrite):
        '''
        Triggered when the read mode is changed to write mode.

        :param isWrite: (bool)
        '''
        self._applyBT.setVisible(isWrite)
        self._cancelBT.setVisible(isWrite)
        self._rwModeCB.setChecked(isWrite)
        if self.defaultWriteMode in ("rw", "wr"):
            self._rwModeCB.setVisible(True)
        else:
            self._rwModeCB.setVisible(False)

        table_view_model = self._tableView.model()
        if table_view_model is not None:
            table_view_model.setWriteMode(isWrite)
            table_view_model._editable = isWrite
        if isWrite == self._writeMode:
            return
        self._writeMode = isWrite
        valueObj = self.getModelValueObj()
        if isWrite and valueObj is not None:
            w_value = valueObj.wvalue
            value = valueObj.rvalue
            if numpy.array(w_value).shape != numpy.array(value).shape:
                ta = self.getModelObj()
                v = ta.read()
                # @fixme: this is ugly! we should not be writing into the attribute without asking first...
                ta.write(v.rvalue)

    def resetWriteMode(self):
        '''equivalent to self.setWriteMode(self.defaultWriteMode)'''
        if self.defaultWriteMode == "r":
            isWritable = False
        else:
            isWritable = True
        self.setWriteMode(isWritable)

    @classmethod
    def getQtDesignerPluginInfo(cls):
        '''Reimplemented from :meth:`TaurusWidget.getQtDesignerPluginInfo`'''
        ret = TaurusWidget.getQtDesignerPluginInfo()
        ret['module'] = 'taurus.qt.qtgui.table'
        ret['group'] = 'Taurus Views'
        ret['icon'] = "designer:table.png"
        return ret

    def chooseModel(self):
        '''shows a model chooser'''
        from taurus.qt.qtgui.panel import TaurusModelChooser
        selectables = [TaurusElementType.Attribute]
        models, ok = TaurusModelChooser.modelChooserDlg(
            selectables=selectables, singleModel=True)
        if ok and len(models) == 1:
            self.setModel(models[0])

    def setModifiableByUser(self, modifiable):
        '''Reimplemented from :meth:`TaurusWidget.setModifiableByUser`'''
        self.chooseModelAction.setEnabled(modifiable)
        TaurusWidget.setModifiableByUser(self, modifiable)

    def isReadOnly(self):
        '''Reimplemented from :meth:`TaurusWidget.isReadOnly`'''
        return False

    #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
    # QT property definition
    #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-

    model = Qt.pyqtProperty("QString", TaurusWidget.getModel, setModel,
                            TaurusWidget.resetModel)
    writeMode = Qt.pyqtProperty("bool", getWriteMode, setWriteMode,
                                resetWriteMode)
示例#3
0
class TaurusValuesTable(TaurusWidget):
    '''
    A table for displaying and/or editing 1D/2D Taurus attributes
    '''
    _showQuality = False
    _writeMode = False

    def __init__(self, parent=None, designMode=False,
                 defaultWriteMode=None):
        TaurusWidget.__init__(self, parent=parent, designMode=designMode)
        self._tableView = TaurusValuesIOTable(self)
        l = Qt.QGridLayout()
        l.addWidget(self._tableView, 1, 0)
        self._tableView.itemDelegate().editorCreated.connect(self._onEditorCreated)

        if defaultWriteMode is None:
            self.defaultWriteMode = "rw"
        else:
            self.defaultWriteMode = defaultWriteMode

        self._label = TaurusLabel()
        self._label.setBgRole('quality')
        self._label.setFgRole('quality')

        self._units = Qt.QComboBox()

        self._applyBT = Qt.QPushButton('Apply')
        self._cancelBT = Qt.QPushButton('Cancel')
        self._applyBT.clicked.connect(self.okClicked)
        self._cancelBT.clicked.connect(self.cancelClicked)

        self._rwModeCB = Qt.QCheckBox()
        self._rwModeCB.setText('Write mode')
        self._rwModeCB.toggled.connect(self.setWriteMode)

        lv = Qt.QHBoxLayout()
        lv.addWidget(self._label)
        lv.addWidget(self._units)
        l.addLayout(lv, 2, 0)
        l.addWidget(self._rwModeCB, 0, 0)
        lv = Qt.QHBoxLayout()
        lv.addWidget(self._applyBT)
        lv.addWidget(self._cancelBT)
        l.addLayout(lv, 3, 0)
        self._writeMode = False
        self.setLayout(l)
        self._initActions()

    def _initActions(self):
        """Initializes the actions for this widget (currently, the pause action.)
        """
        self._pauseAction = Qt.QAction("&Pause", self)
        self._pauseAction.setShortcuts([Qt.Qt.Key_P, Qt.Qt.Key_Pause])
        self._pauseAction.setCheckable(True)
        self._pauseAction.setChecked(False)
        self.addAction(self._pauseAction)
        self._pauseAction.toggled.connect(self.setPaused)
        self.chooseModelAction = Qt.QAction("Choose &Model", self)
        self.chooseModelAction.setEnabled(self.isModifiableByUser())
        self.addAction(self.chooseModelAction)
        self.chooseModelAction.triggered[()].connect(self.chooseModel)

    def getModelClass(self):
        '''see :meth:`TaurusWidget.getModelClass`'''
        return taurus.core.taurusattribute.TaurusAttribute

    def setModel(self, model):
        '''Reimplemented from :meth:`TaurusWidget.setModel`'''
        TaurusWidget.setModel(self, model)
        model_obj = self.getModelObj()

        if model_obj.isWritable() and self.defaultWriteMode != "r":
            self._writeMode = True
        else:
            self.defaultWriteMode = "r"

        if model_obj is not None:
            self._tableView._attr = model_obj
            if model_obj.type in [DataType.Integer, DataType.Float]:
                if self._writeMode:
                    try:
                        default_unit = str(model_obj.wvalue.units)
                    except AttributeError:
                        default_unit = ''
                else:
                    default_unit = str(model_obj.rvalue.units)
                # TODO: fill the combobox with the compatible units
                self._units.addItem("%s" % default_unit)
                self._units.setCurrentIndex(self._units.findText(default_unit))
                self._units.setEnabled(False)
            else:
                self._units.setVisible(False)
            raiseException = False
            if model_obj.data_format == DataFormat._2D:
                try:
                    dim_x, dim_y = numpy.shape(model_obj.rvalue)
                except ValueError:
                    raiseException = True
            elif model_obj.data_format == DataFormat._1D:
                try:
                    dim_x, dim_y = len(model_obj.rvalue), 1
                except ValueError:
                    raiseException = True
            else:
                raiseException = True
            if raiseException:
                raise Exception('rvalue is invalid')
            self._tableView.setModel([dim_x, dim_y])
        self.setWriteMode(self._writeMode)
        self._label.setModel(model)

    def handleEvent(self, evt_src, evt_type, evt_value):
        '''see :meth:`TaurusWidget.handleEvent`'''
        #@fixme: in some situations, we may miss some config event because of the qmodel not being set. The whole handleEvent Method and setModel method should be re-thought
        model = self._tableView.model()
        if model is None:
            return
        if evt_type in (TaurusEventType.Change,
                        TaurusEventType.Periodic)\
                and evt_value is not None:
            attr = self.getModelObj()
            model.setAttr(attr)
            model.setWriteMode(self._writeMode)

            hh = self._tableView.horizontalHeader()
            hh.setResizeMode(Qt.QHeaderView.Fixed)
            vh = self._tableView.verticalHeader()
            vh.setResizeMode(Qt.QHeaderView.Fixed)
            if self.defaultWriteMode == "r":
                isWritable = False
            else:
                isWritable = True
            writable = isWritable and self._writeMode and\
                attr.isWritable()
            self.setWriteMode(writable)
        elif evt_type == TaurusEventType.Config:
            # force a read to set an attr
            attr = self.getModelObj()
            model.setAttr(attr)

    def contextMenuEvent(self, event):
        '''Reimplemented from :meth:`QWidget.contextMenuEvent`'''
        menu = Qt.QMenu()
        globalPos = event.globalPos()
        menu.addAction(self.chooseModelAction)
        menu.addAction(self._pauseAction)
        if self._writeMode:
            index = self._tableView.selectedIndexes()[0]
            if index.isValid():
                val = self._tableView.model().getReadValue(index)
                if self._tableView.model().getModifiedDict().has_key((index.row(), index.column())):
                    menu.addAction(Qt.QIcon.fromTheme(
                        'edit-undo'), "Reset to original value (%s) " % repr(val), self._tableView.removeChange)
                    menu.addSeparator()
                menu.addAction(Qt.QIcon.fromTheme('process-stop'),
                               "Reset all table", self.askCancel)
                menu.addSeparator()
                menu.addAction(Qt.QIcon.fromTheme('help-browser'),
                               "Help", self._tableView.showHelp)
        menu.exec_(globalPos)
        event.accept()

    def applyChanges(self):
        '''
        Writes table modifications to the device server.
        '''
        tab = self._tableView.model().getModifiedWriteData()
        attr = self.getModelObj()
        if attr.type == DataType.String:
            # String arrays has to be converted to a list
            tab = tab.tolist()
        attr.write(tab)
        self._tableView.model().clearChanges()

    def okClicked(self):
        """This is a SLOT that is being triggered when ACCEPT button is clicked.

        .. note:: This SLOT is called, when user wants to apply table modifications.
                  When no cell was modified it will not be called. When
                  modifications have been done, they will be writen to w_value
                  of an attribute.
        """
        if self._tableView.model().isDirty():
            self.applyChanges()
            self.resetWriteMode()

    def cancelClicked(self):
        """This is a SLOT that is being triggered when CANCEL button is clicked.

        .. note:: This SLOT is called, when user does not want to apply table
                  modifications. When no cell was modified it will not be called.
        """
        if self._tableView.model().isDirty():
            self.askCancel()

    def askCancel(self):
        '''
        Shows a QMessageBox, asking if user wants to cancel all changes. Triggered when user clicks Cancel button.
        '''
        result = Qt.QMessageBox.warning(self, 'Your changes will be lost!',
                                        'Do you want to cancel changes done to the whole table?',
                                        Qt.QMessageBox.Ok | Qt.QMessageBox.Cancel)
        if result == Qt.QMessageBox.Ok:
            self._tableView.cancelChanges()
            self.resetWriteMode()

    def _onEditorCreated(self):
        '''slot called when an editor has been created'''
        self.setWriteMode(self._writeMode)

    def getWriteMode(self):
        '''whether the widget is showing the read or write values

        :return: (bool)'''
        return self._writeMode

    def setWriteMode(self, isWrite):
        '''
        Triggered when the read mode is changed to write mode.

        :param isWrite: (bool)
        '''
        self._applyBT.setVisible(isWrite)
        self._cancelBT.setVisible(isWrite)
        self._rwModeCB.setChecked(isWrite)
        if self.defaultWriteMode in ("rw", "wr"):
            self._rwModeCB.setVisible(True)
        else:
            self._rwModeCB.setVisible(False)

        table_view_model = self._tableView.model()
        if table_view_model is not None:
            table_view_model.setWriteMode(isWrite)
            table_view_model._editable = isWrite
        if isWrite == self._writeMode:
            return
        self._writeMode = isWrite
        valueObj = self.getModelValueObj()
        if isWrite and valueObj is not None:
            w_value = valueObj.wvalue
            value = valueObj.rvalue
            if numpy.array(w_value).shape != numpy.array(value).shape:
                ta = self.getModelObj()
                v = ta.read()
                # @fixme: this is ugly! we should not be writing into the attribute without asking first...
                ta.write(v.rvalue)

    def resetWriteMode(self):
        '''equivalent to self.setWriteMode(self.defaultWriteMode)'''
        if self.defaultWriteMode == "r":
            isWritable = False
        else:
            isWritable = True
        self.setWriteMode(isWritable)

    @classmethod
    def getQtDesignerPluginInfo(cls):
        '''Reimplemented from :meth:`TaurusWidget.getQtDesignerPluginInfo`'''
        ret = TaurusWidget.getQtDesignerPluginInfo()
        ret['module'] = 'taurus.qt.qtgui.table'
        ret['group'] = 'Taurus Views'
        ret['icon'] = "designer:table.png"
        return ret

    def chooseModel(self):
        '''shows a model chooser'''
        from taurus.qt.qtgui.panel import TaurusModelChooser
        selectables = [TaurusElementType.Attribute]
        models, ok = TaurusModelChooser.modelChooserDlg(
            selectables=selectables, singleModel=True)
        if ok and len(models) == 1:
            self.setModel(models[0])

    def setModifiableByUser(self, modifiable):
        '''Reimplemented from :meth:`TaurusWidget.setModifiableByUser`'''
        self.chooseModelAction.setEnabled(modifiable)
        TaurusWidget.setModifiableByUser(self, modifiable)

    def isReadOnly(self):
        '''Reimplemented from :meth:`TaurusWidget.isReadOnly`'''
        return False

    #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
    # QT property definition
    #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-

    model = Qt.pyqtProperty("QString", TaurusWidget.getModel,
                            setModel,
                            TaurusWidget.resetModel)
    writeMode = Qt.pyqtProperty(
        "bool", getWriteMode, setWriteMode, resetWriteMode)