Exemplo n.º 1
0
class SchemeSelector(QWidget):
    
    currentChanged = pyqtSignal()
    changed = pyqtSignal()
    
    def __init__(self, parent=None):
        super(SchemeSelector, self).__init__(parent)
        
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)
        
        self.label = QLabel(_("Scheme:"))
        self.scheme = QComboBox()
        self.label.setBuddy(self.scheme)
        self.add = QPushButton(icons.get('list-add'), '')
        self.remove = QPushButton(icons.get('list-remove'), '')
        layout.addWidget(self.label)
        layout.addWidget(self.scheme)
        layout.addWidget(self.add)
        layout.addWidget(self.remove)
        self.scheme.currentIndexChanged.connect(self.slotSchemeChanged)
        self.add.clicked.connect(self.addClicked)
        self.remove.clicked.connect(self.removeClicked)
        app.translateUI(self)
        
    def translateUI(self):
        self.label.setText(_("Scheme:"))
        self.add.setText(_("New Scheme", "&New..."))
        self.remove.setText(_("&Remove"))
        
    def slotSchemeChanged(self, index):
        """Called when the Scheme combobox is changed by the user."""
        self.remove.setEnabled(bool(index))
        self.currentChanged.emit()
        self.changed.emit()
    
    def schemes(self):
        """Returns the list with internal names of currently available schemes."""
        return self._schemes
        
    def currentScheme(self):
        """Returns the internal name of the currently selected scheme"""
        return self._schemes[self.scheme.currentIndex()]
        
    def removeClicked(self):
        index = self.scheme.currentIndex()
        if index == 0:
            return # default can not be removed
        
        self._schemesToRemove.add(self._schemes[index])
        del self._schemes[index]
        del self._schemeNames[index]
        self.scheme.removeItem(index)
    
    def addClicked(self):
        name, ok = QInputDialog.getText(self,
            app.caption("Add Scheme"),
            _("Please enter a name for the new scheme:"))
        if not ok:
            return
        num, key = 1, 'user1'
        while key in self._schemes or key in self._schemesToRemove:
            num += 1
            key = 'user{0}'.format(num)
        self._schemes.append(key)
        self._schemeNames.append(name)
        self.scheme.addItem(name)
        self.scheme.setCurrentIndex(self.scheme.count() - 1)
        
    def loadSettings(self, currentKey, namesGroup):
        # dont mark schemes for removal anymore
        self._schemesToRemove = set()
        
        s = QSettings()
        cur = s.value(currentKey, "default")
        
        # load the names for the shortcut schemes
        s.beginGroup(namesGroup)
        self._schemes = ["default"]
        self._schemeNames = [_("Default")]
        for key in s.childKeys():
            self._schemes.append(key)
            self._schemeNames.append(s.value(key, key))
        block = self.scheme.blockSignals(True)
        self.scheme.clear()
        self.scheme.addItems(self._schemeNames)
        
        # find out index
        index = self._schemes.index(cur) if cur in self._schemes else 0
        self.remove.setEnabled(bool(index))
        self.scheme.setCurrentIndex(index)
        self.scheme.blockSignals(block)
        self.currentChanged.emit()
        
    def saveSettings(self, currentKey, namesGroup, removePrefix=None):
        # first save new scheme names
        s = QSettings()
        s.beginGroup(namesGroup)
        for scheme, name in zip(self._schemes, self._schemeNames)[1:]:
            s.setValue(scheme, name)
        # then remove removed schemes
        for scheme in self._schemesToRemove:
            s.remove(scheme)
        s.endGroup()
        if removePrefix:
            for scheme in self._schemesToRemove:
                s.remove("{0}/{1}".format(removePrefix, scheme))
        # then save current
        scheme = self.currentScheme()
        s.setValue(currentKey, scheme)
        # clean up
        self._schemesToRemove = set()
Exemplo n.º 2
0
class ComboChoice(HelpedWidget):
    """
    A combo box widget for choices.
    List of objects retrieved from model
    str(item) is used for presentation
    getValue and setValue uses the same object as from the list
    """
    def __init__(self, model, combo_label="Choice", help_link=""):
        HelpedWidget.__init__(self, combo_label, help_link)

        assert model is not None and isinstance(model, ChoiceModelMixin)
        self.model = model


        model.observable().attach(ChoiceModelMixin.CURRENT_CHOICE_CHANGED_EVENT, self.getCurrentFromModel)
        model.observable().attach(ChoiceModelMixin.CHOICE_LIST_CHANGED_EVENT, self.updateChoicesFromModel)

        self.combo = QComboBox()

        self.combo.addItem("Fail!")

        self.addWidget(self.combo)
        self.addStretch()

        self.choice_list = None
        """ @type: list """

        self.connect(self.combo, SIGNAL('currentIndexChanged(int)'), self.selectionChanged)

        self.updateChoicesFromModel()
        self.getCurrentFromModel()


    def selectionChanged(self, index):
        assert 0 <= index < len(self.choice_list), "Should not happen! Index out of range: 0 <= %i < %i" % (index, len(self.choice_list))

        item = self.choice_list[index]
        self.model.setCurrentChoice(item)


    def getCurrentFromModel(self):
        new_value = self.model.getCurrentChoice()

        if self.choice_list is None:
            self.updateChoicesFromModel()

        if new_value in self.choice_list:
            index = self.choice_list.index(new_value)
            if not index == self.combo.currentIndex():
                self.combo.setCurrentIndex(index)
        else:
            self.combo.setCurrentIndex(0)

            #sys.stderr.write("AssertionError: ComboBox can not be set to: " + str(new_value) + "\n")
            # raise AssertionError("ComboBox can not be set to: " + str(new_value))


    def updateChoicesFromModel(self):
        block = self.combo.signalsBlocked()
        self.combo.blockSignals(True)

        self.choice_list = self.model.getChoices()

        self.combo.clear()
        for choice in self.choice_list:
            self.combo.addItem(str(choice))

        self.combo.blockSignals(block)
class IndustrialDualAnalogInV2(COMCUPluginBase):
    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletIndustrialDualAnalogInV2, *args)

        self.analog_in = self.device

        self.cbe_voltage0 = CallbackEmulator(functools.partial(self.analog_in.get_voltage, 0),
                                             functools.partial(self.cb_voltage, 0),
                                             self.increase_error_count)

        self.cbe_voltage1 = CallbackEmulator(functools.partial(self.analog_in.get_voltage, 1),
                                             functools.partial(self.cb_voltage, 1),
                                             self.increase_error_count)

        self.calibration = None

        self.sample_rate_label = QLabel('Sample Rate:')
        self.sample_rate_combo = QComboBox()
        self.sample_rate_combo.addItem('976 Hz')
        self.sample_rate_combo.addItem('488 Hz')
        self.sample_rate_combo.addItem('244 Hz')
        self.sample_rate_combo.addItem('122 Hz')
        self.sample_rate_combo.addItem('61 Hz')
        self.sample_rate_combo.addItem('4 Hz')
        self.sample_rate_combo.addItem('2 Hz')
        self.sample_rate_combo.addItem('1 Hz')

        self.current_voltage = [None, None] # float, V
        self.calibration_button = QPushButton('Calibration...')

        self.sample_rate_combo.currentIndexChanged.connect(self.sample_rate_combo_index_changed)
        self.calibration_button.clicked.connect(self.calibration_button_clicked)

        plots = [('Channel 0', Qt.red, lambda: self.current_voltage[0], format_voltage),
                 ('Channel 1', Qt.blue, lambda: self.current_voltage[1], format_voltage)]
        self.plot_widget = PlotWidget('Voltage [V]', plots)

        # Define lines
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        line1 = QFrame()
        line1.setFrameShape(QFrame.HLine)
        line1.setFrameShadow(QFrame.Sunken)

        line2 = QFrame()
        line2.setFrameShape(QFrame.HLine)
        line2.setFrameShadow(QFrame.Sunken)

        # Define channel LED status config widgets
        self.led_config_ch0_label = QLabel('Channel 0')
        self.led_config_ch1_label = QLabel('Channel 1')
        self.led_config_label = QLabel('LED Config:')
        self.led_status_config_label = QLabel('LED Status Config:')
        self.led_status_config_ch0_min_label = QLabel('Min:')
        self.led_status_config_ch0_max_label = QLabel('Max:')
        self.led_status_config_ch1_min_label = QLabel('Min:')
        self.led_status_config_ch1_max_label = QLabel('Max:')

        self.led_config_ch0_combo = QComboBox()
        self.led_config_ch0_combo.addItem('Off')
        self.led_config_ch0_combo.addItem('On')
        self.led_config_ch0_combo.addItem('Show Heartbeat')
        self.led_config_ch0_combo.addItem('Show Channel Status')
        self.led_config_ch0_combo.currentIndexChanged.connect(self.led_config_ch0_combo_changed)

        self.led_config_ch1_combo = QComboBox()
        self.led_config_ch1_combo.addItem('Off')
        self.led_config_ch1_combo.addItem('On')
        self.led_config_ch1_combo.addItem('Show Heartbeat')
        self.led_config_ch1_combo.addItem('Show Channel Status')
        self.led_config_ch1_combo.currentIndexChanged.connect(self.led_config_ch1_combo_changed)

        self.led_status_config_ch0_combo = QComboBox()
        self.led_status_config_ch0_combo.addItem('Threshold')
        self.led_status_config_ch0_combo.addItem('Intensity')
        self.led_status_config_ch0_combo.currentIndexChanged.connect(self.led_status_config_ch0_combo_changed)

        self.led_status_config_ch1_combo = QComboBox()
        self.led_status_config_ch1_combo.addItem('Threshold')
        self.led_status_config_ch1_combo.addItem('Intensity')
        self.led_status_config_ch1_combo.currentIndexChanged.connect(self.led_status_config_ch1_combo_changed)

        self.led_status_config_ch0_min_sbox = QSpinBox()
        self.led_status_config_ch0_min_sbox.setMinimum(-35000)
        self.led_status_config_ch0_min_sbox.setMaximum(35000)
        self.led_status_config_ch0_min_sbox.setValue(0)
        self.led_status_config_ch0_min_sbox.setSingleStep(1)
        self.led_status_config_ch0_min_sbox.setSuffix(' mV')
        self.led_status_config_ch0_min_sbox.valueChanged.connect(self.led_status_config_ch0_min_sbox_changed)

        self.led_status_config_ch0_max_sbox = QSpinBox()
        self.led_status_config_ch0_max_sbox.setMinimum(-35000)
        self.led_status_config_ch0_max_sbox.setMaximum(35000)
        self.led_status_config_ch0_max_sbox.setValue(0)
        self.led_status_config_ch0_max_sbox.setSingleStep(1)
        self.led_status_config_ch0_max_sbox.setSuffix(' mV')
        self.led_status_config_ch0_max_sbox.valueChanged.connect(self.led_status_config_ch0_max_sbox_changed)

        self.led_status_config_ch1_min_sbox = QSpinBox()
        self.led_status_config_ch1_min_sbox.setMinimum(-35000)
        self.led_status_config_ch1_min_sbox.setMaximum(35000)
        self.led_status_config_ch1_min_sbox.setValue(0)
        self.led_status_config_ch1_min_sbox.setSingleStep(1)
        self.led_status_config_ch1_min_sbox.setSuffix(' mV')
        self.led_status_config_ch1_min_sbox.valueChanged.connect(self.led_status_config_ch1_min_sbox_changed)

        self.led_status_config_ch1_max_sbox = QSpinBox()
        self.led_status_config_ch1_max_sbox.setMinimum(-35000)
        self.led_status_config_ch1_max_sbox.setMaximum(35000)
        self.led_status_config_ch1_max_sbox.setValue(0)
        self.led_status_config_ch1_max_sbox.setSingleStep(1)
        self.led_status_config_ch1_max_sbox.setSuffix(' mV')
        self.led_status_config_ch1_max_sbox.valueChanged.connect(self.led_status_config_ch1_max_sbox_changed)

        # Define size policies
        h_sp = QSizePolicy()
        h_sp.setHorizontalPolicy(QSizePolicy.Expanding)

        # Set size policies
        self.sample_rate_combo.setSizePolicy(h_sp)
        self.led_config_ch0_combo.setSizePolicy(h_sp)
        self.led_config_ch1_combo.setSizePolicy(h_sp)
        self.led_status_config_ch0_combo.setSizePolicy(h_sp)
        self.led_status_config_ch1_combo.setSizePolicy(h_sp)
        self.led_status_config_ch0_min_sbox.setSizePolicy(h_sp)
        self.led_status_config_ch0_max_sbox.setSizePolicy(h_sp)
        self.led_status_config_ch1_min_sbox.setSizePolicy(h_sp)
        self.led_status_config_ch1_max_sbox.setSizePolicy(h_sp)

        # Define layouts
        hlayout = QHBoxLayout()
        vlayout = QVBoxLayout()
        glayout = QGridLayout()
        layout = QVBoxLayout(self)
        hlayout_ch0_min_max = QHBoxLayout()
        hlayout_ch1_min_max = QHBoxLayout()

        # Populate layouts
        vlayout.addWidget(self.calibration_button)
        hlayout.addWidget(self.sample_rate_label)
        hlayout.addWidget(self.sample_rate_combo)
        vlayout.addLayout(hlayout)
        vlayout.addWidget(line1)

        hlayout_ch0_min_max.addWidget(self.led_status_config_ch0_min_label)
        hlayout_ch0_min_max.addWidget(self.led_status_config_ch0_min_sbox)
        hlayout_ch0_min_max.addWidget(self.led_status_config_ch0_max_label)
        hlayout_ch0_min_max.addWidget(self.led_status_config_ch0_max_sbox)

        hlayout_ch1_min_max.addWidget(self.led_status_config_ch1_min_label)
        hlayout_ch1_min_max.addWidget(self.led_status_config_ch1_min_sbox)
        hlayout_ch1_min_max.addWidget(self.led_status_config_ch1_max_label)
        hlayout_ch1_min_max.addWidget(self.led_status_config_ch1_max_sbox)

        glayout.addWidget(self.led_config_ch0_label, 0, 1, 1, 1) # R, C, RS, CS
        glayout.addWidget(self.led_config_ch1_label, 0, 2, 1, 1)

        glayout.addWidget(line2, 1, 0, 1, 3)

        glayout.addWidget(self.led_config_label, 2, 0, 1, 1)
        glayout.addWidget(self.led_config_ch0_combo, 2, 1, 1, 1)
        glayout.addWidget(self.led_config_ch1_combo, 2, 2, 1, 1)

        glayout.addWidget(self.led_status_config_label, 3, 0, 1, 1)
        glayout.addWidget(self.led_status_config_ch0_combo, 3, 1, 1, 1)
        glayout.addWidget(self.led_status_config_ch1_combo, 3, 2, 1, 1)

        glayout.addLayout(hlayout_ch0_min_max, 4, 1, 1, 1)
        glayout.addLayout(hlayout_ch1_min_max, 4, 2, 1, 1)

        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(vlayout)
        layout.addLayout(glayout)

        self.ui_group_ch_status_ch0 = [self.led_status_config_ch0_combo,
                                       self.led_status_config_ch0_min_sbox,
                                       self.led_status_config_ch0_max_sbox]

        self.ui_group_ch_status_ch1 = [self.led_status_config_ch1_combo,
                                       self.led_status_config_ch1_min_sbox,
                                       self.led_status_config_ch1_max_sbox]

    def start(self):
        async_call(self.analog_in.get_voltage, 0, lambda x: self.cb_voltage(0, x), self.increase_error_count)
        async_call(self.analog_in.get_voltage, 1, lambda x: self.cb_voltage(1, x), self.increase_error_count)
        async_call(self.analog_in.get_sample_rate, None, self.get_sample_rate_async, self.increase_error_count)
        async_call(self.analog_in.get_channel_led_config,
                   CH_0,
                   lambda config: self.get_channel_led_config_async(CH_0, config),
                   self.increase_error_count)
        async_call(self.analog_in.get_channel_led_status_config,
                   CH_0,
                   lambda config: self.get_channel_led_status_config_async(CH_0, config),
                   self.increase_error_count)
        async_call(self.analog_in.get_channel_led_config,
                   CH_1,
                   lambda config: self.get_channel_led_config_async(CH_1, config),
                   self.increase_error_count)
        async_call(self.analog_in.get_channel_led_status_config,
                   CH_1,
                   lambda config: self.get_channel_led_status_config_async(CH_1, config),
                   self.increase_error_count)

        self.cbe_voltage0.set_period(100)
        self.cbe_voltage1.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_voltage0.set_period(0)
        self.cbe_voltage1.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        if self.calibration != None:
            self.calibration.close()

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletIndustrialDualAnalogInV2.DEVICE_IDENTIFIER

    def calibration_button_clicked(self):
        if self.calibration == None:
            self.calibration = Calibration(self)

        self.calibration_button.setEnabled(False)
        self.calibration.show()

    def sample_rate_combo_index_changed(self, index):
        async_call(self.analog_in.set_sample_rate, index, None, self.increase_error_count)

    def led_config_ch0_combo_changed(self, index):
        if index != self.analog_in.CHANNEL_LED_CONFIG_SHOW_CHANNEL_STATUS:
            for e in self.ui_group_ch_status_ch0:
                e.setEnabled(False)
        else:
            for e in self.ui_group_ch_status_ch0:
                e.setEnabled(True)

        self.analog_in.set_channel_led_config(CH_0, index)

    def led_config_ch1_combo_changed(self, index):
        if index != self.analog_in.CHANNEL_LED_CONFIG_SHOW_CHANNEL_STATUS:
            for e in self.ui_group_ch_status_ch1:
                e.setEnabled(False)
        else:
            for e in self.ui_group_ch_status_ch1:
                e.setEnabled(True)

        self.analog_in.set_channel_led_config(CH_1, index)

    def led_status_config_ch0_combo_changed(self, index):
        self.analog_in.set_channel_led_status_config(CH_0,
                                                     self.led_status_config_ch0_min_sbox.value(),
                                                     self.led_status_config_ch0_max_sbox.value(),
                                                     index)

    def led_status_config_ch1_combo_changed(self, index):
        self.analog_in.set_channel_led_status_config(CH_1,
                                                     self.led_status_config_ch1_min_sbox.value(),
                                                     self.led_status_config_ch1_max_sbox.value(),
                                                     index)

    def led_status_config_ch0_min_sbox_changed(self, value):
        QObject.sender(self).blockSignals(True)

        self.analog_in.set_channel_led_status_config(CH_0,
                                                     self.led_status_config_ch0_min_sbox.value(),
                                                     self.led_status_config_ch0_max_sbox.value(),
                                                     self.led_status_config_ch0_combo.currentIndex())

        QObject.sender(self).blockSignals(False)

    def led_status_config_ch0_max_sbox_changed(self, value):
        QObject.sender(self).blockSignals(True)

        self.analog_in.set_channel_led_status_config(CH_0,
                                                     self.led_status_config_ch0_min_sbox.value(),
                                                     self.led_status_config_ch0_max_sbox.value(),
                                                     self.led_status_config_ch0_combo.currentIndex())

        QObject.sender(self).blockSignals(False)

    def led_status_config_ch1_min_sbox_changed(self, value):
        QObject.sender(self).blockSignals(True)


        self.analog_in.set_channel_led_status_config(CH_1,
                                                     self.led_status_config_ch1_min_sbox.value(),
                                                     self.led_status_config_ch1_max_sbox.value(),
                                                     self.led_status_config_ch1_combo.currentIndex())

        QObject.sender(self).blockSignals(False)

    def led_status_config_ch1_max_sbox_changed(self, value):
        QObject.sender(self).blockSignals(True)

        self.analog_in.set_channel_led_status_config(CH_1,
                                                     self.led_status_config_ch1_min_sbox.value(),
                                                     self.led_status_config_ch1_max_sbox.value(),
                                                     self.led_status_config_ch1_combo.currentIndex())

        QObject.sender(self).blockSignals(False)

    def get_voltage_value0(self):
        return self.voltage_value[0]

    def get_voltage_value1(self):
        return self.voltage_value[1]

    def get_sample_rate_async(self, rate):
        self.sample_rate_combo.blockSignals(True)

        self.sample_rate_combo.setCurrentIndex(rate)

        self.sample_rate_combo.blockSignals(False)

    def get_channel_led_config_async(self, channel, config):
        self.led_config_ch0_combo.blockSignals(True)
        self.led_config_ch1_combo.blockSignals(True)

        if channel == CH_0:
            self.led_config_ch0_combo.setCurrentIndex(config)
        elif channel == CH_1:
            self.led_config_ch1_combo.setCurrentIndex(config)

        self.led_config_ch0_combo.blockSignals(False)
        self.led_config_ch1_combo.blockSignals(False)

    def get_channel_led_status_config_async(self, channel, config):
        self.led_status_config_ch0_combo.blockSignals(True)
        self.led_status_config_ch1_combo.blockSignals(True)

        if channel == CH_0:
            self.led_status_config_ch0_combo.setCurrentIndex(config.config)
            self.led_status_config_ch0_max_sbox.setValue(config.max)
            self.led_status_config_ch0_min_sbox.setValue(config.min)
        elif channel == CH_1:
            self.led_status_config_ch1_combo.setCurrentIndex(config.config)
            self.led_status_config_ch1_max_sbox.setValue(config.max)
            self.led_status_config_ch1_min_sbox.setValue(config.min)

        self.led_status_config_ch0_combo.blockSignals(False)
        self.led_status_config_ch1_combo.blockSignals(False)

    def cb_voltage(self, sensor, voltage):
        self.current_voltage[sensor] = voltage / 1000.0
Exemplo n.º 4
0
class ComboChoice(HelpedWidget):
    """
    A combo box widget for choices.
    List of objects retrieved from model
    str(item) is used for presentation
    getValue and setValue uses the same object as from the list
    """
    def __init__(self, model, combo_label="Choice", help_link=""):
        HelpedWidget.__init__(self, combo_label, help_link)

        assert model is not None and isinstance(model, ChoiceModelMixin)
        self.model = model

        model.observable().attach(
            ChoiceModelMixin.CURRENT_CHOICE_CHANGED_EVENT,
            self.getCurrentFromModel)
        model.observable().attach(ChoiceModelMixin.CHOICE_LIST_CHANGED_EVENT,
                                  self.updateChoicesFromModel)

        self.combo = QComboBox()
        self.combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)

        self.combo.addItem("Fail!")

        self.addWidget(self.combo)
        self.addStretch()

        self.choice_list = None
        """ @type: list """

        self.connect(self.combo, SIGNAL('currentIndexChanged(int)'),
                     self.selectionChanged)

        self.updateChoicesFromModel()
        self.getCurrentFromModel()

    def selectionChanged(self, index):
        assert 0 <= index < len(
            self.choice_list
        ), "Should not happen! Index out of range: 0 <= %i < %i" % (
            index, len(self.choice_list))

        item = self.choice_list[index]
        self.model.setCurrentChoice(item)

    def getCurrentFromModel(self):
        new_value = self.model.getCurrentChoice()

        if self.choice_list is None:
            self.updateChoicesFromModel()

        if new_value in self.choice_list:
            index = self.choice_list.index(new_value)
            if not index == self.combo.currentIndex():
                self.combo.setCurrentIndex(index)
        else:
            self.combo.setCurrentIndex(0)

            #sys.stderr.write("AssertionError: ComboBox can not be set to: " + str(new_value) + "\n")
            # raise AssertionError("ComboBox can not be set to: " + str(new_value))

    def updateChoicesFromModel(self):
        block = self.combo.signalsBlocked()
        self.combo.blockSignals(True)

        self.choice_list = self.model.getChoices()

        self.combo.clear()
        for choice in self.choice_list:
            self.combo.addItem(str(choice))

        self.combo.blockSignals(block)

    def cleanup(self):
        self.model.observable().detach(
            ChoiceModelMixin.CURRENT_CHOICE_CHANGED_EVENT,
            self.getCurrentFromModel)
        self.model.observable().detach(
            ChoiceModelMixin.CHOICE_LIST_CHANGED_EVENT,
            self.updateChoicesFromModel)
class XViewProfileManager(QWidget):
    currentProfileChanged = qt.Signal(qt.PyObject)
    optionsMenuRequested  = qt.Signal(QPoint)
    
    def __init__( self, parent = None ):
        super(XViewProfileManager, self).__init__(parent)
        
        # define custom properties
        self._profiles           = []
        self._optionsMenuPolicy  = Qt.DefaultContextMenu
        self._viewWidget         = None
        
        # define the interface
        self._profileCombo  = QComboBox(self)
        self._optionsButton = QToolButton(self)
        self._optionsButton.setAutoRaise(True)
        self._optionsButton.setToolTip('Advanced Options')
        self._optionsButton.setIcon(QIcon(resources.find('img/advanced.png')))
        
        layout = QHBoxLayout()
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        
        layout.addWidget(self._profileCombo)
        layout.addWidget(self._optionsButton)
        
        self.setLayout(layout)
        
        # create connections
        self._profileCombo.currentIndexChanged.connect(self.handleProfileChange)
        self._optionsButton.clicked.connect(self.showOptionsMenu)
    
    def addProfile( self, profile ):
        """
        Adds the inputed profile to the system.
        
        :param      profile | <XViewProfile>
        """
        if ( profile in self._profiles ):
            return
        
        self._profiles.append(profile)
        self._profileCombo.blockSignals(True)
        self._profileCombo.addItem(profile.name())
        self._profileCombo.setCurrentIndex(self._profileCombo.count()-1)
        self._profileCombo.blockSignals(False)
    
    def currentProfile( self ):
        """
        Returns the currently selected profile from the system.
        
        :return     <XViewProfile>
        """
        index = self._profileCombo.currentIndex()
        
        if ( 0 <= index and index < len(self._profiles) ):
            return self._profiles[index]
        return None
    
    def handleProfileChange( self ):
        """
        Emits that the current profile has changed.
        """
        # restore the profile settings
        prof    = self.currentProfile()
        vwidget = self.viewWidget()
        if ( vwidget ):
            prof.restore(vwidget)
        
        if ( not self.signalsBlocked() ):
            self.currentProfileChanged.emit(self.currentProfile())
    
    def optionsMenuPolicy( self ):
        """
        Returns the option menu policy for this widget.
        
        :return     <Qt.MenuPolicy>
        """
        return self._optionsMenuPolicy
    
    def profiles( self ):
        """
        Returns a list of all the profiles for this system.
        
        :return     [<XViewProfile>, ..]
        """
        return self._profiles
    
    def removeProfile( self, profile ):
        """
        Adds the inputed profile to the system.
        
        :param      profile | <XViewProfile>
        """
        if ( not profile in self._profiles ):
            return
        
        index = self._profiles.index(profile)
        self._profiles.remove(profile)
        self._profileCombo.blockSignals(True)
        self._profileCombo.takeItem(index)
        self._profileCombo.blockSignals(False)
    
    def restoreSettings( self, settings ):
        """
        Restores settings from the application.
        
        :param      settings | <QSettings>
        """
        settings.beginGroup(self.objectName())
        
        curr_prof = None
        curr_name = qt.unwrapVariant(settings.value('current'))
        
        profiles = []
        for prof_name in settings.childGroups():
            settings.beginGroup(prof_name)
            
            prof_str = qt.unwrapVariant(settings.value('profile'))
            profile  = XViewProfile.fromString(prof_str)
            profile.setName(prof_name)
            
            if ( prof_name == curr_name ):
                curr_prof = profile
            
            profiles.append(profile)
            
            settings.endGroup()
        
        self.blockSignals(True)
        self._profileCombo.blockSignals(True)
        self.setProfiles(profiles)
        
        if ( curr_prof ):
            self.setCurrentProfile(curr_prof)
        
        self._profileCombo.blockSignals(False)
        self.blockSignals(False)
        
        settings.endGroup()
    
    def saveSettings( self, settings ):
        """
        Saves the settings for this widget to the application
        
        :param      settings | <QSettings>
        """
        settings.beginGroup(self.objectName())
        
        curr_prof = self.currentProfile()
        if ( curr_prof ):
            settings.setValue('current', curr_prof.name())
        
        for profile in self.profiles():
            settings.beginGroup(profile.name())
            settings.setValue('profile', qt.wrapVariant(profile.toString()))
            settings.endGroup()
        
        settings.endGroup()
    
    def setCurrentProfile( self, profile ):
        """
        Sets the current profile to the inputed profile.
        
        :param      profile | <XViewProfile>
        """
        try:
            index = self._profiles.index(profile)
        except ValueError:
            index = -1
        
        self._profileCombo.setCurrentIndex(index)
    
    def setOptionsMenuPolicy( self, menuPolicy ):
        """
        Sets the options menu policy for this item.
        
        :param      menuPolicy | <Qt.MenuPolicy>
        """
        self._optionsMenuPolicy = menuPolicy
    
    def setProfiles( self, profiles ):
        """
        Sets a list of profiles to be the options for the manager.
        
        :param      profiles | [<XViewProfile>, ..]
        """
        self.blockSignals(True)
        self._profileCombo.blockSignals(True)
        
        self._profiles = profiles[:]
        self._profileCombo.clear()
        self._profileCombo.addItems(map(lambda x: x.name(), profiles))
        
        self._profileCombo.blockSignals(False)
        self.blockSignals(False)
    
    def setViewWidget( self, viewWidget ):
        """
        Sets the view widget instance linked with this manager.
        
        :param      viewWidget | <XViewWidget>
        """
        self._viewWidget = viewWidget
    
    def showOptionsMenu( self ):
        """
        Displays the options menu.  If the option menu policy is set to 
        CustomContextMenu, then the optionMenuRequested signal will be emitted,
        otherwise the default context menu will be displayed.
        """
        point        = QPoint(0, self._optionsButton.height())
        global_point = self._optionsButton.mapToGlobal(point)
        
        # prompt the custom context menu
        if ( self.optionsMenuPolicy() == Qt.CustomContextMenu ):
            if ( not self.signalsBlocked() ):
                self.optionsMenuRequested.emit(global_point)
            return
        
        # use the default context menu
        menu = XViewProfileManagerMenu(self)
        menu.exec_(global_point)
    
    def viewWidget( self ):
        """
        Returns the view widget that is associated with this manager.
        
        :return     <XViewWidget>
        """
        return self._viewWidget
Exemplo n.º 6
0
class Thermocouple(PluginBase):
    qtcb_error_state = pyqtSignal(bool, bool)

    def __init__(self, *args):
        PluginBase.__init__(self, BrickletThermocouple, *args)

        self.thermo = self.device

        self.qtcb_error_state.connect(self.cb_error_state)
        self.thermo.register_callback(self.thermo.CALLBACK_ERROR_STATE,
                                      self.qtcb_error_state.emit)

        self.cbe_temperature = CallbackEmulator(self.thermo.get_temperature,
                                                self.cb_temperature,
                                                self.increase_error_count)

        self.current_temperature = None  # float, °C

        self.error_label = QLabel('Current Errors: None')
        self.error_label.setAlignment(Qt.AlignVCenter | Qt.AlignRight)

        plots = [('Temperature', Qt.red, lambda: self.current_temperature,
                  u'{:.2f} °C'.format)]
        self.plot_widget = PlotWidget(u'Temperature [°C]',
                                      plots,
                                      extra_key_widgets=[self.error_label])

        self.averaging_label = QLabel('Averaging:')
        self.averaging_combo = QComboBox()
        self.averaging_combo.addItem('1', BrickletThermocouple.AVERAGING_1)
        self.averaging_combo.addItem('2', BrickletThermocouple.AVERAGING_2)
        self.averaging_combo.addItem('4', BrickletThermocouple.AVERAGING_4)
        self.averaging_combo.addItem('8', BrickletThermocouple.AVERAGING_8)
        self.averaging_combo.addItem('16', BrickletThermocouple.AVERAGING_16)

        self.type_label = QLabel('Thermocouple Type:')
        self.type_combo = QComboBox()
        self.type_combo.addItem('B', BrickletThermocouple.TYPE_B)
        self.type_combo.addItem('E', BrickletThermocouple.TYPE_E)
        self.type_combo.addItem('J', BrickletThermocouple.TYPE_J)
        self.type_combo.addItem('K', BrickletThermocouple.TYPE_K)
        self.type_combo.addItem('N', BrickletThermocouple.TYPE_N)
        self.type_combo.addItem('R', BrickletThermocouple.TYPE_R)
        self.type_combo.addItem('S', BrickletThermocouple.TYPE_S)
        self.type_combo.addItem('T', BrickletThermocouple.TYPE_T)
        self.type_combo.addItem('Gain 8', BrickletThermocouple.TYPE_G8)
        self.type_combo.addItem('Gain 32', BrickletThermocouple.TYPE_G32)

        self.filter_label = QLabel('Noise Rejection Filter:')
        self.filter_combo = QComboBox()
        self.filter_combo.addItem('50 Hz',
                                  BrickletThermocouple.FILTER_OPTION_50HZ)
        self.filter_combo.addItem('60 Hz',
                                  BrickletThermocouple.FILTER_OPTION_60HZ)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.averaging_label)
        hlayout.addWidget(self.averaging_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.type_label)
        hlayout.addWidget(self.type_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.filter_label)
        hlayout.addWidget(self.filter_combo)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(hlayout)

        self.averaging_combo.currentIndexChanged.connect(
            self.configuration_changed)
        self.type_combo.currentIndexChanged.connect(self.configuration_changed)
        self.filter_combo.currentIndexChanged.connect(
            self.configuration_changed)

    def start(self):
        async_call(self.thermo.get_temperature, None, self.cb_temperature,
                   self.increase_error_count)
        async_call(self.thermo.get_configuration, None, self.cb_configuration,
                   self.increase_error_count)
        async_call(self.thermo.get_error_state, None,
                   lambda e: self.cb_error_state(e.over_under, e.open_circuit))
        self.cbe_temperature.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_temperature.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletThermocouple.DEVICE_IDENTIFIER

    def get_current_value(self):
        return self.current_value

    def configuration_changed(self, _):
        conf_averaging = self.averaging_combo.itemData(
            self.averaging_combo.currentIndex())
        conf_type = self.type_combo.itemData(self.type_combo.currentIndex())
        conf_filter = self.filter_combo.itemData(
            self.filter_combo.currentIndex())

        self.thermo.set_configuration(conf_averaging, conf_type, conf_filter)

    def cb_temperature(self, temperature):
        self.current_temperature = temperature / 100.0

    def cb_configuration(self, conf):
        self.averaging_combo.blockSignals(True)
        self.averaging_combo.setCurrentIndex(
            self.averaging_combo.findData(conf.averaging))
        self.averaging_combo.blockSignals(False)

        self.type_combo.blockSignals(True)
        self.type_combo.setCurrentIndex(
            self.type_combo.findData(conf.thermocouple_type))
        self.type_combo.blockSignals(False)

        self.filter_combo.blockSignals(True)
        self.filter_combo.setCurrentIndex(
            self.filter_combo.findData(conf.filter))
        self.filter_combo.blockSignals(False)

    def cb_error_state(self, over_under, open_circuit):
        if over_under or open_circuit:
            text = 'Current Errors: '
            if over_under:
                text += 'Over/Under Voltage'
            if over_under and open_circuit:
                text += ' and '
            if open_circuit:
                text += 'Open Circuit\n(defective thermocouple or nothing connected)'

            self.error_label.setStyleSheet('QLabel { color : red }')
            self.error_label.setText(text)
        else:
            self.error_label.setStyleSheet('')
            self.error_label.setText('Current Errors: None')
Exemplo n.º 7
0
class Thermocouple(PluginBase):
    AVERAGING = [BrickletThermocouple.AVERAGING_1, BrickletThermocouple.AVERAGING_2, BrickletThermocouple.AVERAGING_4, BrickletThermocouple.AVERAGING_8, BrickletThermocouple.AVERAGING_16]
    THERMOCOUPLE_TYPE = [BrickletThermocouple.TYPE_B, BrickletThermocouple.TYPE_E, BrickletThermocouple.TYPE_J, BrickletThermocouple.TYPE_K, BrickletThermocouple.TYPE_N, BrickletThermocouple.TYPE_R, BrickletThermocouple.TYPE_S, BrickletThermocouple.TYPE_T, BrickletThermocouple.TYPE_G8, BrickletThermocouple.TYPE_G32]
    FILTER_TYPE = [BrickletThermocouple.FILTER_OPTION_50HZ, BrickletThermocouple.FILTER_OPTION_60HZ]
    
    qtcb_error_state = pyqtSignal(bool, bool)
    
    def __init__(self, *args):
        PluginBase.__init__(self, BrickletThermocouple, *args)
        
        self.thermo = self.device
        
        self.qtcb_error_state.connect(self.cb_error_state)
        self.thermo.register_callback(self.thermo.CALLBACK_ERROR_STATE,
                                      self.qtcb_error_state.emit)

        self.cbe_temperature = CallbackEmulator(self.thermo.get_temperature,
                                                self.cb_temperature,
                                                self.increase_error_count)

        self.temperature_label = TemperatureLabel()
        
        self.current_value = None
        
        plot_list = [['', Qt.red, self.get_current_value]]
        self.plot_widget = PlotWidget('Temperature [%cC]' % 0xB0, plot_list)

        self.averaging_label = QLabel('Averaging:')
        self.averaging_combo = QComboBox()
        self.averaging_combo.addItem('1 sample')
        self.averaging_combo.addItem('2 samples')
        self.averaging_combo.addItem('4 samples')
        self.averaging_combo.addItem('8 samples')
        self.averaging_combo.addItem('16 samples')
        
        self.type_label = QLabel('Thermocouple Type:')
        self.type_combo = QComboBox()
        self.type_combo.addItem('B')
        self.type_combo.addItem('E')
        self.type_combo.addItem('J')
        self.type_combo.addItem('K')
        self.type_combo.addItem('N')
        self.type_combo.addItem('R')
        self.type_combo.addItem('S')
        self.type_combo.addItem('T')
        self.type_combo.addItem('Gain 8')
        self.type_combo.addItem('Gain 32')
        
        self.filter_label = QLabel('Noise Rejection Filter:')
        self.filter_combo = QComboBox()
        self.filter_combo.addItem('50Hz')
        self.filter_combo.addItem('60Hz')
        
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        
        self.error_label = QLabel('Current errors: None')
        
        layout_conf = QHBoxLayout()
        layout_conf.addWidget(self.averaging_label)
        layout_conf.addWidget(self.averaging_combo)
        layout_conf.addStretch()
        layout_conf.addWidget(self.type_label)
        layout_conf.addWidget(self.type_combo)
        layout_conf.addStretch()
        layout_conf.addWidget(self.filter_label)
        layout_conf.addWidget(self.filter_combo)
        
        layout_error = QHBoxLayout()
        layout_error.addStretch()
        layout_error.addWidget(self.error_label)
        layout_error.addStretch()
        
        layout_h = QHBoxLayout()
        layout_h.addStretch()
        layout_h.addWidget(self.temperature_label)
        layout_h.addStretch()

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h)
        layout.addWidget(self.plot_widget)
        layout.addLayout(layout_conf)
        layout.addWidget(line)
        layout.addLayout(layout_error)
        
        self.averaging_combo.currentIndexChanged.connect(self.configuration_changed)
        self.type_combo.currentIndexChanged.connect(self.configuration_changed)
        self.filter_combo.currentIndexChanged.connect(self.configuration_changed)
        
        
    def start(self):
        async_call(self.thermo.get_temperature, None, self.cb_temperature, self.increase_error_count)
        async_call(self.thermo.get_configuration, None, self.cb_configuration, self.increase_error_count)
        async_call(self.thermo.get_error_state, None, lambda e: self.cb_error_state(e.over_under, e.open_circuit))
        self.cbe_temperature.set_period(100)
        
        self.plot_widget.stop = False
        
    def stop(self):
        self.cbe_temperature.set_period(0)
        
        self.plot_widget.stop = True

    def destroy(self):
        pass

    def get_url_part(self):
        return 'temperature'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletThermocouple.DEVICE_IDENTIFIER

    def get_current_value(self):
        return self.current_value
    
    def configuration_changed(self, _):
        conf_averaging = Thermocouple.AVERAGING[self.averaging_combo.currentIndex()]
        conf_type = Thermocouple.THERMOCOUPLE_TYPE[self.type_combo.currentIndex()]
        conf_filter = Thermocouple.FILTER_TYPE[self.filter_combo.currentIndex()]
        
        self.thermo.set_configuration(conf_averaging, conf_type, conf_filter)

    def cb_temperature(self, temperature):
        self.current_value = temperature/100.0
        self.temperature_label.setText(str(temperature/100.0))

    def cb_configuration(self, conf):
        self.averaging_combo.blockSignals(True)
        if conf.averaging == self.thermo.AVERAGING_1:
            self.averaging_combo.setCurrentIndex(0)
        elif conf.averaging == self.thermo.AVERAGING_2:
            self.averaging_combo.setCurrentIndex(1)
        elif conf.averaging == self.thermo.AVERAGING_4:
            self.averaging_combo.setCurrentIndex(2)
        elif conf.averaging == self.thermo.AVERAGING_8:
            self.averaging_combo.setCurrentIndex(3)
        elif conf.averaging == self.thermo.AVERAGING_16:
            self.averaging_combo.setCurrentIndex(4)
        self.averaging_combo.blockSignals(False)
            
        self.type_combo.blockSignals(True)
        if conf.thermocouple_type == self.thermo.TYPE_B:
            self.type_combo.setCurrentIndex(0)
        elif conf.thermocouple_type == self.thermo.TYPE_E:
            self.type_combo.setCurrentIndex(1)
        elif conf.thermocouple_type == self.thermo.TYPE_J:
            self.type_combo.setCurrentIndex(2)
        elif conf.thermocouple_type == self.thermo.TYPE_K:
            self.type_combo.setCurrentIndex(3)
        elif conf.thermocouple_type == self.thermo.TYPE_N:
            self.type_combo.setCurrentIndex(4)
        elif conf.thermocouple_type == self.thermo.TYPE_R:
            self.type_combo.setCurrentIndex(5)
        elif conf.thermocouple_type == self.thermo.TYPE_S:
            self.type_combo.setCurrentIndex(6)
        elif conf.thermocouple_type == self.thermo.TYPE_T:
            self.type_combo.setCurrentIndex(7)
        elif conf.thermocouple_type == self.thermo.TYPE_G8:
            self.type_combo.setCurrentIndex(8)
        elif conf.thermocouple_type == self.thermo.TYPE_G32:
            self.type_combo.setCurrentIndex(9)
        self.type_combo.blockSignals(False)

        self.filter_combo.blockSignals(True)
        if conf.filter == self.thermo.FILTER_OPTION_50HZ:
            self.filter_combo.setCurrentIndex(0)
        elif conf.filter == self.thermo.FILTER_OPTION_60HZ:
            self.filter_combo.setCurrentIndex(1)
        self.filter_combo.blockSignals(False)
        
    def cb_error_state(self, over_under, open_circuit):
        if over_under or open_circuit:
            text = 'Current errors: '
            if over_under:
                text += 'Over/Under Voltage'
            if over_under and open_circuit:
                text += ' and '
            if open_circuit:
                text += 'Open Circuit (defective thermocouple or nothing connected)'
                
            self.error_label.setStyleSheet('QLabel { color : red }')
            self.error_label.setText(text)
        else:
            self.error_label.setStyleSheet('')
            self.error_label.setText('Current errors: None')
            
Exemplo n.º 8
0
class ScoringDialog(QWidget):
    """a dialog for entering the scores"""
    # pylint: disable=R0902
    # pylint we need more than 10 instance attributes

    scoringClosed = pyqtSignal()

    def __init__(self, game):
        QWidget.__init__(self, None)
        self.game = None
        self.setWindowTitle(m18n('Scoring for this Hand') + ' - Kajongg')
        self.nameLabels = [None] * 4
        self.spValues = [None] * 4
        self.windLabels = [None] * 4
        self.wonBoxes = [None] * 4
        self.detailsLayout = [None] * 4
        self.details = [None] * 4
        self.__tilePixMaps = []
        self.__meldPixMaps = []
        grid = QGridLayout(self)
        pGrid = QGridLayout()
        grid.addLayout(pGrid, 0, 0, 2, 1)
        pGrid.addWidget(QLabel(m18nc('kajongg', "Player")), 0, 0)
        pGrid.addWidget(QLabel(m18nc('kajongg', "Wind")), 0, 1)
        pGrid.addWidget(QLabel(m18nc('kajongg', 'Score')), 0, 2)
        pGrid.addWidget(QLabel(m18n("Winner")), 0, 3)
        self.detailTabs = QTabWidget()
        self.detailTabs.setDocumentMode(True)
        pGrid.addWidget(self.detailTabs, 0, 4, 8, 1)
        for idx in range(4):
            self.setupUiForPlayer(pGrid, idx)
        self.draw = QCheckBox(m18nc('kajongg','Draw'))
        self.draw.clicked.connect(self.wonChanged)
        btnPenalties = QPushButton(m18n("&Penalties"))
        btnPenalties.clicked.connect(self.penalty)
        self.btnSave = QPushButton(m18n('&Save Hand'))
        self.btnSave.setEnabled(False)
        self.setupUILastTileMeld(pGrid)
        pGrid.setRowStretch(87, 10)
        pGrid.addWidget(self.draw, 7, 3)
        self.cbLastTile.currentIndexChanged.connect(self.slotLastTile)
        self.cbLastMeld.currentIndexChanged.connect(self.slotInputChanged)
        btnBox = QHBoxLayout()
        btnBox.addWidget(btnPenalties)
        btnBox.addWidget(self.btnSave)
        pGrid.addLayout(btnBox, 8, 4)
        StateSaver(self)
        self.refresh(game)

    def setupUILastTileMeld(self, pGrid):
        """setup UI elements for last tile and last meld"""
        self.lblLastTile = QLabel(m18n('&Last Tile:'))
        self.cbLastTile = QComboBox()
        self.cbLastTile.setMinimumContentsLength(1)
        vpol = QSizePolicy()
        vpol.setHorizontalPolicy(QSizePolicy.Fixed)
        self.cbLastTile.setSizePolicy(vpol)
        self.cbLastTile.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.lblLastTile.setBuddy(self.cbLastTile)
        self.lblLastMeld = QLabel(m18n('L&ast Meld:'))
        self.prevLastTile = None
        self.cbLastMeld = QComboBox()
        self.cbLastMeld.setMinimumContentsLength(1)
        self.cbLastMeld.setSizePolicy(vpol)
        self.cbLastMeld.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.lblLastMeld.setBuddy(self.cbLastMeld)
        self.comboTilePairs = set()
        pGrid.setRowStretch(6, 5)
        pGrid.addWidget(self.lblLastTile, 7, 0, 1, 2)
        pGrid.addWidget(self.cbLastTile, 7, 2, 1, 1)
        pGrid.addWidget(self.lblLastMeld, 8, 0, 1, 2)
        pGrid.addWidget(self.cbLastMeld, 8, 2, 1, 2)

    def setupUiForPlayer(self, pGrid, idx):
        """setup UI elements for a player"""
        self.spValues[idx] = QSpinBox()
        self.nameLabels[idx] = QLabel()
        self.nameLabels[idx].setBuddy(self.spValues[idx])
        self.windLabels[idx] = WindLabel()
        pGrid.addWidget(self.nameLabels[idx], idx+2, 0)
        pGrid.addWidget(self.windLabels[idx], idx+2, 1)
        pGrid.addWidget(self.spValues[idx], idx+2, 2)
        self.wonBoxes[idx] = QCheckBox("")
        pGrid.addWidget(self.wonBoxes[idx], idx+2, 3)
        self.wonBoxes[idx].clicked.connect(self.wonChanged)
        self.spValues[idx].valueChanged.connect(self.slotInputChanged)
        detailTab = QWidget()
        self.detailTabs.addTab(detailTab,'')
        self.details[idx] = QWidget()
        detailTabLayout = QVBoxLayout(detailTab)
        detailTabLayout.addWidget(self.details[idx])
        detailTabLayout.addStretch()
        self.detailsLayout[idx] = QVBoxLayout(self.details[idx])


    def refresh(self, game):
        """reload game"""
        if game and not game.isScoringGame():
            return
        self.game = game
        self.clear()
        self.setVisible(game is not None and not game.finished())
        if game:
            for idx, player in enumerate(game.players):
                for child in self.details[idx].children():
                    if isinstance(child, RuleBox):
                        child.hide()
                        self.detailsLayout[idx].removeWidget(child)
                        del child
                if game:
                    self.spValues[idx].setRange(0, game.ruleset.limit or 99999)
                    self.nameLabels[idx].setText(player.localName)
                    self.windLabels[idx].wind = player.wind
                    self.windLabels[idx].roundsFinished = game.roundsFinished
                    self.detailTabs.setTabText(idx, player.localName)
                    player.manualRuleBoxes = [RuleBox(x) for x in game.ruleset.allRules if x.hasSelectable]
                    for ruleBox in player.manualRuleBoxes:
                        self.detailsLayout[idx].addWidget(ruleBox)
                        ruleBox.clicked.connect(self.slotInputChanged)
                player.refreshManualRules()

    def show(self):
        """only now compute content"""
        if self.game and not self.game.finished():
            self.slotInputChanged()
            QWidget.show(self)

    def penalty(self):
        """penalty button clicked"""
        dlg = PenaltyDialog(self.game)
        dlg.exec_()

    def slotLastTile(self):
        """called when the last tile changes"""
        newLastTile = self.computeLastTile()
        if not newLastTile:
            return
        prevLower, newLower = self.prevLastTile.islower(), newLastTile.islower()
        if prevLower != newLower:
            # state of last tile (concealed/exposed) changed:
            # for all checked boxes check if they still are applicable
            winner = self.game.winner
            if winner:
                for box in winner.manualRuleBoxes:
                    if box.isChecked():
                        box.setChecked(False)
                        if winner.hand.manualRuleMayApply(box.rule):
                            box.setChecked(True)
        self.prevLastTile = newLastTile
        self.fillLastMeldCombo()
        self.slotInputChanged()

    def computeLastTile(self):
        """returns the currently selected last tile"""
        idx = self.cbLastTile.currentIndex()
        if idx >= 0:
            return str(self.cbLastTile.itemData(idx).toString())

    def closeEvent(self, event):
        """the user pressed ALT-F4"""
        self.hide()
        event.ignore()
        self.scoringClosed.emit()

    def clickedPlayerIdx(self, checkbox):
        """the player whose box has been clicked"""
        for idx in range(4):
            if checkbox == self.wonBoxes[idx]:
                return idx
        assert False

    def wonChanged(self):
        """if a new winner has been defined, uncheck any previous winner"""
        newWinner = None
        if self.sender() != self.draw:
            clicked = self.clickedPlayerIdx(self.sender())
            if self.wonBoxes[clicked].isChecked():
                newWinner = self.game.players[clicked]
            else:
                newWinner = None
        self.game.winner = newWinner
        for idx in range(4):
            if newWinner != self.game.players[idx]:
                self.wonBoxes[idx].setChecked(False)
        if newWinner:
            self.draw.setChecked(False)
        self.fillLastTileCombo()
        self.slotInputChanged()

    def updateManualRules(self):
        """enable/disable them"""
        # if an exclusive rule has been activated, deactivate it for
        # all other players
        if isinstance(self.sender(), RuleBox):
            ruleBox = self.sender()
            if ruleBox.isChecked() and ruleBox.rule.exclusive():
                for idx, player in enumerate(self.game.players):
                    if ruleBox.parentWidget() != self.details[idx]:
                        for pBox in player.manualRuleBoxes:
                            if pBox.rule.name == ruleBox.rule.name:
                                pBox.setChecked(False)
        try:
            newState = bool(self.game.winner.handBoard.tiles)
        except AttributeError:
            newState = False
        self.lblLastTile.setEnabled(newState)
        self.cbLastTile.setEnabled(newState)
        self.lblLastMeld.setEnabled(newState)
        self.cbLastMeld.setEnabled(newState)
        if self.game:
            for player in self.game.players:
                player.refreshManualRules(self.sender())

    def clear(self):
        """prepare for next hand"""
        if self.game:
            for idx, player in enumerate(self.game.players):
                self.spValues[idx].clear()
                self.spValues[idx].setValue(0)
                self.wonBoxes[idx].setChecked(False)
                player.payment = 0
                player.invalidateHand()
        for box in self.wonBoxes:
            box.setVisible(False)
        self.draw.setChecked(False)
        self.updateManualRules()

        if self.game is None:
            self.hide()
        else:
            for idx, player in enumerate(self.game.players):
                self.windLabels[idx].setPixmap(WINDPIXMAPS[(player.wind,
                            player.wind == WINDS[self.game.roundsFinished % 4])])
            self.computeScores()
            self.spValues[0].setFocus()
            self.spValues[0].selectAll()

    def computeScores(self):
        """if tiles have been selected, compute their value"""
        # pylint: disable=R0912
        # too many branches
        if not self.game:
            return
        if self.game.finished():
            self.hide()
            return
        for idx, player in enumerate(self.game.players):
            self.spValues[idx].blockSignals(True) # we do not want that change to call computeScores again
            self.wonBoxes[idx].blockSignals(True) # we do not want that change to call computeScores again
            if player.handBoard and player.handBoard.tiles:
                self.spValues[idx].setEnabled(False)
                self.nameLabels[idx].setBuddy(self.wonBoxes[idx])
                for loop in range(10):
                    prevTotal = player.handTotal
                    handContent = player.computeHand(asWinner=True)
                    self.wonBoxes[idx].setVisible(handContent.won)
                    if not self.wonBoxes[idx].isVisibleTo(self) and self.wonBoxes[idx].isChecked():
                        self.wonBoxes[idx].setChecked(False)
                        self.game.winner = None
                    elif prevTotal == player.handTotal:
                        break
                    player.refreshManualRules()
                self.spValues[idx].setValue(player.handTotal)
            else:
                if not self.spValues[idx].isEnabled():
                    self.spValues[idx].clear()
                    self.spValues[idx].setValue(0)
                    self.spValues[idx].setEnabled(True)
                    self.nameLabels[idx].setBuddy(self.spValues[idx])
                self.wonBoxes[idx].setVisible(player.handTotal >= self.game.ruleset.minMJTotal())
                if not self.wonBoxes[idx].isVisibleTo(self) and self.wonBoxes[idx].isChecked():
                    self.wonBoxes[idx].setChecked(False)
            if not self.wonBoxes[idx].isVisibleTo(self) and player is self.game.winner:
                self.game.winner = None
            self.spValues[idx].blockSignals(False)
            self.wonBoxes[idx].blockSignals(False)
        if Internal.field.explainView:
            Internal.field.explainView.refresh(self.game)

    def __lastMeldContent(self):
        """prepare content for lastmeld combo"""
        lastTiles = set()
        winnerTiles = []
        if self.game.winner and self.game.winner.handBoard:
            winnerTiles = self.game.winner.handBoard.tiles
            pairs = []
            for meld in self.game.winner.hand.melds:
                if len(meld) < 4:
                    pairs.extend(meld.pairs)
            for tile in winnerTiles:
                if tile.element in pairs and not tile.isBonus():
                    lastTiles.add(tile.element)
        return lastTiles, winnerTiles

    def __fillLastTileComboWith(self, lastTiles, winnerTiles):
        """fill last meld combo with prepared content"""
        self.comboTilePairs = lastTiles
        idx = self.cbLastTile.currentIndex()
        if idx < 0:
            idx = 0
        indexedTile = str(self.cbLastTile.itemData(idx).toPyObject())
        restoredIdx = None
        self.cbLastTile.clear()
        if not winnerTiles:
            return
        pmSize = winnerTiles[0].board.tileset.faceSize
        pmSize = QSize(pmSize.width() * 0.5, pmSize.height() * 0.5)
        self.cbLastTile.setIconSize(pmSize)
        QPixmapCache.clear()
        self.__tilePixMaps = []
        shownTiles = set()
        for tile in winnerTiles:
            if tile.element in lastTiles and tile.element not in shownTiles:
                shownTiles.add(tile.element)
                self.cbLastTile.addItem(QIcon(tile.graphics.pixmapFromSvg(pmSize, withBorders=False)),
                        '', QVariant(tile.element))
                if indexedTile == tile.element:
                    restoredIdx = self.cbLastTile.count() - 1
        if not restoredIdx and indexedTile:
            # try again, maybe the tile changed between concealed and exposed
            indexedTile = indexedTile.lower()
            for idx in range(self.cbLastTile.count()):
                if indexedTile == str(self.cbLastTile.itemData(idx).toPyObject()).lower():
                    restoredIdx = idx
                    break
        if not restoredIdx:
            restoredIdx = 0
        self.cbLastTile.setCurrentIndex(restoredIdx)
        self.prevLastTile = self.computeLastTile()

    def clearLastTileCombo(self):
        """as the name says"""
        self.comboTilePairs = None
        self.cbLastTile.clear()

    def fillLastTileCombo(self):
        """fill the drop down list with all possible tiles.
        If the drop down had content before try to preserve the
        current index. Even if the tile changed state meanwhile."""
        if self.game is None:
            return
        lastTiles, winnerTiles = self.__lastMeldContent()
        if self.comboTilePairs == lastTiles:
            return
        self.cbLastTile.blockSignals(True) # we only want to emit the changed signal once
        try:
            self.__fillLastTileComboWith(lastTiles, winnerTiles)
        finally:
            self.cbLastTile.blockSignals(False)
            self.cbLastTile.currentIndexChanged.emit(0)

    def __fillLastMeldComboWith(self, winnerMelds, indexedMeld, lastTile):
        """fill last meld combo with prepared content"""
        winner = self.game.winner
        faceWidth = winner.handBoard.tileset.faceSize.width() * 0.5
        faceHeight = winner.handBoard.tileset.faceSize.height() * 0.5
        restoredIdx = None
        for meld in winnerMelds:
            pixMap = QPixmap(faceWidth * len(meld), faceHeight)
            pixMap.fill(Qt.transparent)
            self.__meldPixMaps.append(pixMap)
            painter = QPainter(pixMap)
            for element in meld.pairs:
                painter.drawPixmap(0, 0,
                    winner.handBoard.tilesByElement(element) \
                    [0].graphics.pixmapFromSvg(QSize(faceWidth, faceHeight), withBorders=False))
                painter.translate(QPointF(faceWidth, 0.0))
            self.cbLastMeld.addItem(QIcon(pixMap), '', QVariant(meld.joined))
            if indexedMeld == meld.joined:
                restoredIdx = self.cbLastMeld.count() - 1
        if not restoredIdx and indexedMeld:
            # try again, maybe the meld changed between concealed and exposed
            indexedMeld = indexedMeld.lower()
            for idx in range(self.cbLastMeld.count()):
                meldContent = str(self.cbLastMeld.itemData(idx).toPyObject())
                if indexedMeld == meldContent.lower():
                    restoredIdx = idx
                    if lastTile not in meldContent:
                        if lastTile.lower() == lastTile:
                            lastTile = lastTile.capitalize()
                        else:
                            lastTile = lastTile.lower()
                        assert lastTile in meldContent
                        self.cbLastTile.blockSignals(True) # we want to continue right here
                        idx = self.cbLastTile.findData(QVariant(lastTile))
                        self.cbLastTile.setCurrentIndex(idx)
                        self.cbLastTile.blockSignals(False)
                    break
        if not restoredIdx:
            restoredIdx = 0
        self.cbLastMeld.setCurrentIndex(restoredIdx)
        self.cbLastMeld.setIconSize(QSize(faceWidth * 3, faceHeight))

    def fillLastMeldCombo(self):
        """fill the drop down list with all possible melds.
        If the drop down had content before try to preserve the
        current index. Even if the meld changed state meanwhile."""
        self.cbLastMeld.blockSignals(True) # we only want to emit the changed signal once
        try:
            showCombo = False
            idx = self.cbLastMeld.currentIndex()
            if idx < 0:
                idx = 0
            indexedMeld = str(self.cbLastMeld.itemData(idx).toPyObject())
            self.cbLastMeld.clear()
            self.__meldPixMaps = []
            if not self.game.winner:
                return
            if self.cbLastTile.count() == 0:
                return
            lastTile = Internal.field.computeLastTile()
            winnerMelds = [m for m in self.game.winner.hand.melds if len(m) < 4 \
                and lastTile in m.pairs]
            assert len(winnerMelds)
            if len(winnerMelds) == 1:
                self.cbLastMeld.addItem(QIcon(), '', QVariant(winnerMelds[0].joined))
                self.cbLastMeld.setCurrentIndex(0)
                return
            showCombo = True
            self.__fillLastMeldComboWith(winnerMelds, indexedMeld, lastTile)
        finally:
            self.lblLastMeld.setVisible(showCombo)
            self.cbLastMeld.setVisible(showCombo)
            self.cbLastMeld.blockSignals(False)
            self.cbLastMeld.currentIndexChanged.emit(0)

    def slotInputChanged(self):
        """some input fields changed: update"""
        for player in self.game.players:
            player.invalidateHand()
        self.updateManualRules()
        self.computeScores()
        self.validate()

    def validate(self):
        """update the status of the OK button"""
        game = self.game
        if game:
            valid = True
            if game.winner and game.winner.handTotal < game.ruleset.minMJTotal():
                valid = False
            elif not game.winner and not self.draw.isChecked():
                valid = False
            self.btnSave.setEnabled(valid)
Exemplo n.º 9
0
class SchemeSelector(QWidget):

    currentChanged = pyqtSignal()
    changed = pyqtSignal()

    def __init__(self, parent=None):
        super(SchemeSelector, self).__init__(parent)
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        self.label = QLabel()
        self.scheme = QComboBox()
        self.menuButton = QPushButton(flat=True)
        menu = QMenu(self.menuButton)
        self.menuButton.setMenu(menu)
        layout.addWidget(self.label)
        layout.addWidget(self.scheme)
        layout.addWidget(self.menuButton)
        layout.addStretch(1)

        # action generator
        def act(slot, icon=None):
            a = QAction(self, triggered=slot)
            self.addAction(a)
            icon and a.setIcon(icons.get(icon))
            return a

        # add action
        a = self.addAction_ = act(self.slotAdd, 'list-add')
        menu.addAction(a)

        # remove action
        a = self.removeAction = act(self.slotRemove, 'list-remove')
        menu.addAction(a)

        # rename action
        a = self.renameAction = act(self.slotRename, 'document-edit')
        menu.addAction(a)

        menu.addSeparator()

        # import action
        a = self.importAction = act(self.slotImport, 'document-open')
        menu.addAction(a)

        # export action
        a = self.exportAction = act(self.slotExport, 'document-save-as')
        menu.addAction(a)

        self.scheme.currentIndexChanged.connect(self.slotSchemeChanged)
        app.translateUI(self)

    def translateUI(self):
        self.label.setText(_("Scheme:"))
        self.menuButton.setText(_("&Menu"))
        self.addAction_.setText(_("&Add..."))
        self.removeAction.setText(_("&Remove"))
        self.renameAction.setText(_("Re&name..."))
        self.importAction.setText(_("&Import..."))
        self.exportAction.setText(_("&Export..."))

    def slotSchemeChanged(self, index):
        """Called when the Scheme combobox is changed by the user."""
        self.disableDefault(self.scheme.itemData(index) == 'default')
        self.currentChanged.emit()
        self.changed.emit()

    def disableDefault(self, val):
        self.removeAction.setDisabled(val)
        self.renameAction.setDisabled(val)

    def schemes(self):
        """Returns the list with internal names of currently available schemes."""
        return [self.scheme.itemData(i) for i in range(self.scheme.count())]

    def currentScheme(self):
        """Returns the internal name of the currently selected scheme"""
        return self.scheme.itemData(self.scheme.currentIndex())

    def insertSchemeItem(self, name, scheme):
        for i in range(1, self.scheme.count()):
            n = self.scheme.itemText(i)
            if n.lower() > name.lower():
                self.scheme.insertItem(i, name, scheme)
                break
        else:
            self.scheme.addItem(name, scheme)

    def addScheme(self, name):
        num, key = 1, 'user1'
        while key in self.schemes() or key in self._schemesToRemove:
            num += 1
            key = 'user{0}'.format(num)
        self.insertSchemeItem(name, key)
        self.scheme.setCurrentIndex(self.scheme.findData(key))
        return key

    def slotAdd(self):
        name, ok = QInputDialog.getText(
            self, app.caption(_("Add Scheme")),
            _("Please enter a name for the new scheme:"))
        if ok:
            self.addScheme(name)

    def slotRemove(self):
        index = self.scheme.currentIndex()
        scheme = self.scheme.itemData(index)
        if scheme == 'default':
            return  # default can not be removed

        self._schemesToRemove.add(scheme)
        self.scheme.removeItem(index)

    def slotRename(self):
        index = self.scheme.currentIndex()
        name = self.scheme.itemText(index)
        scheme = self.scheme.itemData(index)
        newName, ok = QInputDialog.getText(self,
                                           _("Rename"),
                                           _("New name:"),
                                           text=name)
        if ok:
            self.scheme.blockSignals(True)
            self.scheme.removeItem(index)
            self.insertSchemeItem(newName, scheme)
            self.scheme.setCurrentIndex(self.scheme.findData(scheme))
            self.scheme.blockSignals(False)
            self.changed.emit()

    def slotImport(self):
        filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"),
                                                  _("All Files"))
        caption = app.caption(_("dialog title", "Import color theme"))
        filename = QFileDialog.getOpenFileName(self, caption, QDir.homePath(),
                                               filetypes)
        if filename:
            self.parent().import_(filename)

    def slotExport(self):
        name = self.scheme.currentText()
        filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"),
                                                  _("All Files"))
        caption = app.caption(
            _("dialog title", "Export {name}").format(name=name))
        path = os.path.join(QDir.homePath(), name + '.xml')
        filename = QFileDialog.getSaveFileName(self, caption, path, filetypes)
        if filename:
            if os.path.splitext(filename)[1] != '.xml':
                filename += '.xml'
            self.parent().export(name, filename)

    def loadSettings(self, currentKey, namesGroup):
        # don't mark schemes for removal anymore
        self._schemesToRemove = set()

        s = QSettings()
        cur = s.value(currentKey, "default", type(""))

        # load the names for the shortcut schemes
        s.beginGroup(namesGroup)
        block = self.scheme.blockSignals(True)
        self.scheme.clear()
        self.scheme.addItem(_("Default"), "default")
        lst = [(s.value(key, key, type("")), key) for key in s.childKeys()]
        for name, key in sorted(lst, key=lambda f: f[0].lower()):
            self.scheme.addItem(name, key)

        # find out index
        index = self.scheme.findData(cur)
        self.disableDefault(cur == 'default')
        self.scheme.setCurrentIndex(index)
        self.scheme.blockSignals(block)
        self.currentChanged.emit()

    def saveSettings(self, currentKey, namesGroup, removePrefix=None):
        # first save new scheme names
        s = QSettings()
        s.beginGroup(namesGroup)
        for i in range(self.scheme.count()):
            if self.scheme.itemData(i) != 'default':
                s.setValue(self.scheme.itemData(i), self.scheme.itemText(i))

        for scheme in self._schemesToRemove:
            s.remove(scheme)
        s.endGroup()
        if removePrefix:
            for scheme in self._schemesToRemove:
                s.remove("{0}/{1}".format(removePrefix, scheme))
        # then save current
        scheme = self.currentScheme()
        s.setValue(currentKey, scheme)
        # clean up
        self._schemesToRemove = set()
Exemplo n.º 10
0
class Ui_WidgetReport(QWidget):

  def __init__(self, parent = None):
    ''' '''
    super(Ui_WidgetReport, self).__init__()
    self.__parentWidget = parent
    self.helper = Ui_WidgetReportHelper(self)

    self.cosmos_cli = CosmosClient()
    
    #TODO: these should be in the app configuration tool
    webhdfs_url = 'http://130.206.80.46:14000/webhdfs/v1'
    auth_url = 'https://130.206.80.46:13000/cosmos-auth/v1'
    local_filepath = os.environ['HOME']+os.sep+'.fresh'+os.sep+'history'
    username = '******'
    password = '******'
    cosmos_user = '******'
    serv = 'NA'
    servpath = 'NA'
    #--------------------------
    
    #Tuple(sensor_type, sensor_name)
    self.sensor_list = [#'sensor', 'sensor_1'), 
                        #('sensor', 'sensor_2'), 
                        #('sensor', 'sensor_3'), 
                        #('sensor', 'sensor_4'), 
                        #('sensor', 'sensor_5'),
                        #('sensor', 'sensor_6'),
                        #('sensor', 'sensor_7'),
                        #('sensor', 'sensor_8'),
                        ('sensor', 'sensor_9'),
                        ('sensor', 'sensor_10')] 
    
    self.entity_list = dict()
    
    self.cosmos_cli.username = username
    self.cosmos_cli.password = password
    self.cosmos_cli.webhdfs_url = webhdfs_url
    self.cosmos_cli.auth_url = auth_url
    self.cosmos_cli.hdfs_username = cosmos_user
    self.cosmos_cli.hdfs_filepath = '/'+serv+'_serv/'+servpath+'_servpath/'
    self.cosmos_cli.local_filepath = local_filepath
    
    self.rep_template = preppy.getModule('reportTemplate.prep')
    
    self.setupUi(self)

  #----------------------------------------------------------------------------

  def setupUi(self, WidgetNetMang):
    
    #This view contains a stacked widget with two pages
    
    #1st page plots the graphic:
    
    layout_plot = QGridLayout()
    self.widget_page_plot = QWidget()
    self.widget_page_plot.setLayout(layout_plot)    
    self.axis = DateAxis(orientation='bottom')
    self.widget_plot = pg.PlotWidget(axisItems={'bottom': self.axis})
    self.combo_zone = QComboBox()
    for (_, sensor) in self.sensor_list: self.combo_zone.addItem(sensor)
    self.combo_sensor = QComboBox()
    self.button_refresh = QPushButton()
    self.button_refresh.setText('Refresh')
    self.button_report = QPushButton()
    self.button_report.setText('Report')
    
    #(QWidget, row, column, rowSpan, columnSpan)
    layout_plot.addWidget(self.widget_plot, 0, 0, 1, 5)      
    layout_plot.addWidget(self.combo_zone, 1, 0, 1, 1)
    layout_plot.addWidget(self.combo_sensor, 1, 1, 1, 1)
    layout_plot.addWidget(self.button_report, 1, 3, 1, 1)
    layout_plot.addWidget(self.button_refresh, 1, 4, 1, 1) 
    
    #2nd page shows the report form:
    
    label_requester_name = QLabel('Name:')
    label_requester_addr = QLabel('Address:')
    label_requester_mail = QLabel('Email:')
    self.edit_requester_name = QLineEdit()
    self.edit_requester_addr = QTextEdit()
    self.edit_requester_addr.setMaximumHeight(80)
    self.edit_requester_mail = QLineEdit()
    layout_requester = QGridLayout()
    layout_requester.addWidget(label_requester_name, 0, 0, 1, 1)
    layout_requester.addWidget(self.edit_requester_name, 0, 1, 4, 1)
    layout_requester.addWidget(label_requester_addr, 4, 0, 1, 1)
    layout_requester.addWidget(self.edit_requester_addr, 4, 1, 4, 1)
    layout_requester.addWidget(label_requester_mail, 8, 0, 1, 1)
    layout_requester.addWidget(self.edit_requester_mail, 8, 1, 4, 1)
    group_requester = QGroupBox('Requester')
    group_requester.setLayout(layout_requester)
    
    label_expert_name = QLabel('Name:')
    label_expert_addr = QLabel('Address:')
    label_expert_mail = QLabel('Email:')
    self.edit_expert_name = QLineEdit()
    self.edit_expert_addr = QTextEdit()
    self.edit_expert_addr.setMaximumHeight(80)
    self.edit_expert_mail = QLineEdit()
    layout_expert = QGridLayout()
    layout_expert.addWidget(label_expert_name, 0, 0, 1, 1)
    layout_expert.addWidget(self.edit_expert_name, 0, 1, 4, 1)
    layout_expert.addWidget(label_expert_addr, 4, 0, 1, 1)
    layout_expert.addWidget(self.edit_expert_addr, 4, 1, 4, 1)
    layout_expert.addWidget(label_expert_mail, 8, 0, 1, 1)
    layout_expert.addWidget(self.edit_expert_mail, 8, 1, 4, 1)
    group_expert = QGroupBox('Expert')
    group_expert.setLayout(layout_expert)
    
    self.edit_observations = QTextEdit()
    self.edit_observations.setMaximumHeight(80)
    layout_observations = QGridLayout()
    layout_observations.addWidget(self.edit_observations, 0, 0, 1, 1)
    group_observations = QGroupBox('Observations')
    group_observations.setLayout(layout_observations)
    
    self.label_plot = QLabel()
    self.label_plot.setFixedSize(700, 300)
    self.label_plot.setScaledContents(True)
    layout_group_plot = QGridLayout()
    layout_group_plot.addWidget(self.label_plot, 0, 0, 1, 1)
    group_plot = QGroupBox('Plot Preview')
    group_plot.setLayout(layout_group_plot)
    
    vertical_line = QFrame()
    vertical_line.setFrameShape(QFrame().VLine)
    vertical_line.setFrameShadow(QFrame().Sunken)
    
    layout_frame_form = QGridLayout()
    layout_frame_form.addWidget(group_requester, 0, 0, 1, 1)
    layout_frame_form.addWidget(vertical_line, 0, 1, 1, 1)
    layout_frame_form.addWidget(group_expert, 0, 2, 1, 1)
    layout_frame_form.addWidget(group_observations, 1, 0, 1, 3)
    layout_frame_form.addWidget(group_plot, 2, 0, 1, 3)
    
    frame_form = QFrame()
    frame_form.setLayout(layout_frame_form)
    
    scroll_area = QScrollArea()
    scroll_area.setWidget(frame_form)
    
    
    self.button_form_back = QPushButton()
    self.button_form_save = QPushButton()
    self.button_form_send = QPushButton()
    self.button_form_back.setText('Back')
    self.button_form_save.setText('Save')
    self.button_form_send.setText('Send')
    
    layout_form = QGridLayout()
    layout_form.addWidget(scroll_area, 0, 0, 1, 5)
    layout_form.addWidget(self.button_form_back, 1, 0, 1, 1)
    layout_form.addWidget(self.button_form_save, 1, 3, 1, 1)
    layout_form.addWidget(self.button_form_send, 1, 4, 1, 1)
    
    self.widget_page_form = QWidget()
    self.widget_page_form.setLayout(layout_form)
    
    self.widget_stacked = QStackedWidget(self)
    self.widget_stacked.addWidget(self.widget_page_plot)
    self.widget_stacked.addWidget(self.widget_page_form)
    
    layout_main = QGridLayout()
    layout_main.addWidget(self.widget_stacked)
    self.setLayout(layout_main)
    
    #---
    
    self.combo_zone.currentIndexChanged['QString'].\
      connect(self.handle_combo_zone_changed)
    self.combo_sensor.currentIndexChanged['QString'].\
      connect(self.handle_combo_sensor_changed)
    self.button_refresh.clicked.\
      connect(self.handle_button_refresh_clicked)
    self.button_report.clicked.\
      connect(self.handle_button_report_clicked)
    self.button_form_back.clicked.\
      connect(self.handle_button_form_back_clicked)
    self.button_form_save.clicked.\
      connect(self.handle_button_form_save_clicked)
    self.button_form_send.clicked.\
      connect(self.handle_button_form_send_clicked)
  
  #----------------------------------------------------------------------------
  
  @pyqtSlot('QString')
  def handle_combo_zone_changed(self, text):
    
    if str(text) == '':
      return
    
    self.combo_sensor.blockSignals(True)
    self.combo_sensor.clear()
    for e in self.entity_list[str(text)]:
      self.combo_sensor.addItem(e)
    self.combo_sensor.setCurrentIndex(0)
    self.combo_sensor.blockSignals(False)
    self.combo_sensor.currentIndexChanged['QString'].emit(self.combo_sensor.currentText())
  
  #----------------------------------------------------------------------------
  
  @pyqtSlot('QString')
  def handle_combo_sensor_changed(self, text):
    
    if str(text) == '':
      return
    
    print str(text)
    
    dates = []
    values = []
    
    found = False
    for (s_type,s_name) in self.sensor_list:
      if s_name == str(self.combo_zone.currentText()):
        self.cosmos_cli.local_filename = s_name+'_'+s_type+'.txt'
        found = True
        break;
    
    if not found:
      return
    
    self.cosmos_cli.readHistoryFromFile()
    
    for s in self.cosmos_cli.history.split('\n'):
      try:
        j = json.loads(s)
        try:
          value = j[str(text)]
          date = j['recvTime'].split('.')[0]
          values.append(float(value))
          print date
          print time.mktime(datetime.datetime.strptime(date, "%Y-%m-%dT%H:%M:%S").timetuple())
          dates.append(time.mktime(datetime.datetime.strptime(date, "%Y-%m-%dT%H:%M:%S").timetuple()))
          #dates.append(date.split('T')[0]+'\n'+(date.split('T')[1]).split('.')[0])
        except:
          pass
      except:
        pass

    self.widget_plot.clear()
    #xdates = dict(zip(range(len(dates)),dates))
    #self.axis.set_dict(xdates)
    #self.widget_plot.plot(x=xdates.keys(), y=values, symbol='o')
    self.widget_plot.plot(x=dates, y=values, symbol='o')  
  #----------------------------------------------------------------------------
  
  
  
  @pyqtSlot()
  def handle_button_refresh_clicked(self):
    
    """get the files from cosmos and stores them locally"""
    
    
    self.entity_list.clear()
    
    for (s_type, s_name) in self.sensor_list:
      self.entity_list[s_name] = dict()
      self.cosmos_cli.hdfs_filename = s_name+'_'+s_type+'/'+s_name+'_'+s_type+'.txt'
      self.cosmos_cli.local_filename = s_name+'_'+s_type+'.txt'
      try:
        self.cosmos_cli.getFileContent()
      except NameError as e:
        print e
        return
      try:
        self.cosmos_cli.writeHistoryToFile()
      except NameError as e:
        print e
        return
      
      self.entity_list[s_name].clear()
      for s in self.cosmos_cli.history.split('\n'):
        try:
          for k in json.loads(s).keys():
            if 'md' not in k and 'recv' not in k and 'RTC' not in k:
              self.entity_list[s_name][k] = ''
        except Exception as e:
          print e
          pass
    
    self.combo_zone.clear()
    self.combo_sensor.clear()
    
    for e in self.entity_list:
      self.combo_zone.addItem(e)
      "print self.entity_list[e]"

    #self.combo_sensor.clear()
    #for e in self.entity_list:
    #  self.combo_sensor.addItem(e)

    print "refresh"
    
  #============================================================================

  @pyqtSlot()
  def handle_button_report_clicked(self):
    
    try:
      exporter = pyqtgraph.exporters.ImageExporter(self.widget_plot.plotItem)
      exporter.export(self.cosmos_cli.local_filepath + '/plot.png')
      self.label_plot.setPixmap(QPixmap(self.cosmos_cli.local_filepath + '/plot.png'))
    except Exception as e:
      print e
      return
    
    self.widget_stacked.setCurrentIndex(1)

  #============================================================================

  @pyqtSlot()
  def handle_button_form_back_clicked(self):
    
    self.widget_stacked.setCurrentIndex(0)
  
  #============================================================================

  @pyqtSlot()
  def handle_button_form_save_clicked(self):
 
    rmlText = self.rep_template.get(str(self.combo_zone.currentText())+' - '+
                                    str(self.combo_sensor.currentText()),
                                    datetime.datetime.now().strftime("%Y-%m-%d"),
                                    str(self.edit_requester_name.text()),
                                    str(self.edit_requester_addr.toPlainText()),
                                    '',
                                    str(self.edit_expert_name.text()),
                                    str(self.edit_expert_addr.toPlainText()),
                                    '',
                                    str(self.edit_observations.toPlainText()),
                                    self.cosmos_cli.local_filepath+'/plot.png')
    pdf = rml2pdf.parseString(rmlText)
    
    filename = QFileDialog().getSaveFileName()
    
    if str(filename == ''): return
    
    with open(str(filename), 'w+') as pdfFile:
      pdfFile.write(pdf.read())
 
  #============================================================================

  @pyqtSlot()
  def handle_button_form_send_clicked(self):
    
    rmlText = self.rep_template.get(str(self.combo_zone.currentText())+' - '+
                                    str(self.combo_sensor.currentText()),
                                    datetime.datetime.now().strftime("%Y-%m-%d"),
                                    str(self.edit_requester_name.text()),
                                    str(self.edit_requester_addr.toPlainText()),
                                    str(self.edit_requester_mail.text()),
                                    str(self.edit_expert_name.text()),
                                    str(self.edit_expert_addr.toPlainText()),
                                    str(self.edit_expert_mail.text()),
                                    str(self.edit_observations.toPlainText()),
                                    self.cosmos_cli.local_filepath+'/plot.png')
    pdf = rml2pdf.parseString(rmlText)
    
    with open(self.cosmos_cli.local_filepath+'/rmlReport.pdf', 'w+') as pdfFile:
      pdfFile.write(pdf.read())
    
    time.sleep(1)
    
    (password, ok) = QInputDialog().getText(self, 'password', 'password', mode=QLineEdit.Password)
    
    print str(self.edit_requester_mail.text())
    print str(password)
    
    email_cli = EmailClient(username = str(self.edit_requester_mail.text()),
                            password = str(password))
    
    email_cli.sendEmail(from_addr=str(self.edit_requester_mail.text()),
                        to_addr=str(self.edit_expert_mail.text()),
                        mail_subject='[FRESH Expert Service] Request for Advice',
                        mail_body=str(self.edit_observations.toPlainText()),
                        attachment=self.cosmos_cli.local_filepath+'/rmlReport.pdf')
Exemplo n.º 11
0
class Thermocouple(PluginBase):
    AVERAGING = [
        BrickletThermocouple.AVERAGING_1, BrickletThermocouple.AVERAGING_2,
        BrickletThermocouple.AVERAGING_4, BrickletThermocouple.AVERAGING_8,
        BrickletThermocouple.AVERAGING_16
    ]
    THERMOCOUPLE_TYPE = [
        BrickletThermocouple.TYPE_B, BrickletThermocouple.TYPE_E,
        BrickletThermocouple.TYPE_J, BrickletThermocouple.TYPE_K,
        BrickletThermocouple.TYPE_N, BrickletThermocouple.TYPE_R,
        BrickletThermocouple.TYPE_S, BrickletThermocouple.TYPE_T,
        BrickletThermocouple.TYPE_G8, BrickletThermocouple.TYPE_G32
    ]
    FILTER_TYPE = [
        BrickletThermocouple.FILTER_OPTION_50HZ,
        BrickletThermocouple.FILTER_OPTION_60HZ
    ]

    qtcb_error_state = pyqtSignal(bool, bool)

    def __init__(self, *args):
        PluginBase.__init__(self, BrickletThermocouple, *args)

        self.thermo = self.device

        self.qtcb_error_state.connect(self.cb_error_state)
        self.thermo.register_callback(self.thermo.CALLBACK_ERROR_STATE,
                                      self.qtcb_error_state.emit)

        self.cbe_temperature = CallbackEmulator(self.thermo.get_temperature,
                                                self.cb_temperature,
                                                self.increase_error_count)

        self.temperature_label = TemperatureLabel()

        self.current_value = None

        plot_list = [['', Qt.red, self.get_current_value]]
        self.plot_widget = PlotWidget('Temperature [%cC]' % 0xB0, plot_list)

        self.averaging_label = QLabel('Averaging:')
        self.averaging_combo = QComboBox()
        self.averaging_combo.addItem('1 sample')
        self.averaging_combo.addItem('2 samples')
        self.averaging_combo.addItem('4 samples')
        self.averaging_combo.addItem('8 samples')
        self.averaging_combo.addItem('16 samples')

        self.type_label = QLabel('Thermocouple Type:')
        self.type_combo = QComboBox()
        self.type_combo.addItem('B')
        self.type_combo.addItem('E')
        self.type_combo.addItem('J')
        self.type_combo.addItem('K')
        self.type_combo.addItem('N')
        self.type_combo.addItem('R')
        self.type_combo.addItem('S')
        self.type_combo.addItem('T')
        self.type_combo.addItem('Gain 8')
        self.type_combo.addItem('Gain 32')

        self.filter_label = QLabel('Noise Rejection Filter:')
        self.filter_combo = QComboBox()
        self.filter_combo.addItem('50Hz')
        self.filter_combo.addItem('60Hz')

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        self.error_label = QLabel('Current errors: None')

        layout_conf = QHBoxLayout()
        layout_conf.addWidget(self.averaging_label)
        layout_conf.addWidget(self.averaging_combo)
        layout_conf.addStretch()
        layout_conf.addWidget(self.type_label)
        layout_conf.addWidget(self.type_combo)
        layout_conf.addStretch()
        layout_conf.addWidget(self.filter_label)
        layout_conf.addWidget(self.filter_combo)

        layout_error = QHBoxLayout()
        layout_error.addStretch()
        layout_error.addWidget(self.error_label)
        layout_error.addStretch()

        layout_h = QHBoxLayout()
        layout_h.addStretch()
        layout_h.addWidget(self.temperature_label)
        layout_h.addStretch()

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h)
        layout.addWidget(self.plot_widget)
        layout.addLayout(layout_conf)
        layout.addWidget(line)
        layout.addLayout(layout_error)

        self.averaging_combo.currentIndexChanged.connect(
            self.configuration_changed)
        self.type_combo.currentIndexChanged.connect(self.configuration_changed)
        self.filter_combo.currentIndexChanged.connect(
            self.configuration_changed)

    def start(self):
        async_call(self.thermo.get_temperature, None, self.cb_temperature,
                   self.increase_error_count)
        async_call(self.thermo.get_configuration, None, self.cb_configuration,
                   self.increase_error_count)
        async_call(self.thermo.get_error_state, None,
                   lambda e: self.cb_error_state(e.over_under, e.open_circuit))
        self.cbe_temperature.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_temperature.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    def get_url_part(self):
        return 'temperature'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletThermocouple.DEVICE_IDENTIFIER

    def get_current_value(self):
        return self.current_value

    def configuration_changed(self, _):
        conf_averaging = Thermocouple.AVERAGING[
            self.averaging_combo.currentIndex()]
        conf_type = Thermocouple.THERMOCOUPLE_TYPE[
            self.type_combo.currentIndex()]
        conf_filter = Thermocouple.FILTER_TYPE[
            self.filter_combo.currentIndex()]

        self.thermo.set_configuration(conf_averaging, conf_type, conf_filter)

    def cb_temperature(self, temperature):
        self.current_value = temperature / 100.0
        self.temperature_label.setText(str(temperature / 100.0))

    def cb_configuration(self, conf):
        self.averaging_combo.blockSignals(True)
        if conf.averaging == self.thermo.AVERAGING_1:
            self.averaging_combo.setCurrentIndex(0)
        elif conf.averaging == self.thermo.AVERAGING_2:
            self.averaging_combo.setCurrentIndex(1)
        elif conf.averaging == self.thermo.AVERAGING_4:
            self.averaging_combo.setCurrentIndex(2)
        elif conf.averaging == self.thermo.AVERAGING_8:
            self.averaging_combo.setCurrentIndex(3)
        elif conf.averaging == self.thermo.AVERAGING_16:
            self.averaging_combo.setCurrentIndex(4)
        self.averaging_combo.blockSignals(False)

        self.type_combo.blockSignals(True)
        if conf.thermocouple_type == self.thermo.TYPE_B:
            self.type_combo.setCurrentIndex(0)
        elif conf.thermocouple_type == self.thermo.TYPE_E:
            self.type_combo.setCurrentIndex(1)
        elif conf.thermocouple_type == self.thermo.TYPE_J:
            self.type_combo.setCurrentIndex(2)
        elif conf.thermocouple_type == self.thermo.TYPE_K:
            self.type_combo.setCurrentIndex(3)
        elif conf.thermocouple_type == self.thermo.TYPE_N:
            self.type_combo.setCurrentIndex(4)
        elif conf.thermocouple_type == self.thermo.TYPE_R:
            self.type_combo.setCurrentIndex(5)
        elif conf.thermocouple_type == self.thermo.TYPE_S:
            self.type_combo.setCurrentIndex(6)
        elif conf.thermocouple_type == self.thermo.TYPE_T:
            self.type_combo.setCurrentIndex(7)
        elif conf.thermocouple_type == self.thermo.TYPE_G8:
            self.type_combo.setCurrentIndex(8)
        elif conf.thermocouple_type == self.thermo.TYPE_G32:
            self.type_combo.setCurrentIndex(9)
        self.type_combo.blockSignals(False)

        self.filter_combo.blockSignals(True)
        if conf.filter == self.thermo.FILTER_OPTION_50HZ:
            self.filter_combo.setCurrentIndex(0)
        elif conf.filter == self.thermo.FILTER_OPTION_60HZ:
            self.filter_combo.setCurrentIndex(1)
        self.filter_combo.blockSignals(False)

    def cb_error_state(self, over_under, open_circuit):
        if over_under or open_circuit:
            text = 'Current errors: '
            if over_under:
                text += 'Over/Under Voltage'
            if over_under and open_circuit:
                text += ' and '
            if open_circuit:
                text += 'Open Circuit (defective thermocouple or nothing connected)'

            self.error_label.setStyleSheet('QLabel { color : red }')
            self.error_label.setText(text)
        else:
            self.error_label.setStyleSheet('')
            self.error_label.setText('Current errors: None')
Exemplo n.º 12
0
class XViewProfileManager(QWidget):
    currentProfileChanged = qt.Signal(qt.PyObject)
    optionsMenuRequested = qt.Signal(QPoint)

    def __init__(self, parent=None):
        super(XViewProfileManager, self).__init__(parent)

        # define custom properties
        self._profiles = []
        self._optionsMenuPolicy = Qt.DefaultContextMenu
        self._viewWidget = None

        # define the interface
        self._profileCombo = QComboBox(self)
        self._optionsButton = QToolButton(self)
        self._optionsButton.setAutoRaise(True)
        self._optionsButton.setToolTip('Advanced Options')
        self._optionsButton.setIcon(QIcon(resources.find('img/advanced.png')))

        layout = QHBoxLayout()
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)

        layout.addWidget(self._profileCombo)
        layout.addWidget(self._optionsButton)

        self.setLayout(layout)

        # create connections
        self._profileCombo.currentIndexChanged.connect(
            self.handleProfileChange)
        self._optionsButton.clicked.connect(self.showOptionsMenu)

    def addProfile(self, profile):
        """
        Adds the inputed profile to the system.
        
        :param      profile | <XViewProfile>
        """
        if (profile in self._profiles):
            return

        self._profiles.append(profile)
        self._profileCombo.blockSignals(True)
        self._profileCombo.addItem(profile.name())
        self._profileCombo.setCurrentIndex(self._profileCombo.count() - 1)
        self._profileCombo.blockSignals(False)

    def currentProfile(self):
        """
        Returns the currently selected profile from the system.
        
        :return     <XViewProfile>
        """
        index = self._profileCombo.currentIndex()

        if (0 <= index and index < len(self._profiles)):
            return self._profiles[index]
        return None

    def handleProfileChange(self):
        """
        Emits that the current profile has changed.
        """
        # restore the profile settings
        prof = self.currentProfile()
        vwidget = self.viewWidget()
        if (vwidget):
            prof.restore(vwidget)

        if (not self.signalsBlocked()):
            self.currentProfileChanged.emit(self.currentProfile())

    def optionsMenuPolicy(self):
        """
        Returns the option menu policy for this widget.
        
        :return     <Qt.MenuPolicy>
        """
        return self._optionsMenuPolicy

    def profiles(self):
        """
        Returns a list of all the profiles for this system.
        
        :return     [<XViewProfile>, ..]
        """
        return self._profiles

    def removeProfile(self, profile):
        """
        Adds the inputed profile to the system.
        
        :param      profile | <XViewProfile>
        """
        if (not profile in self._profiles):
            return

        index = self._profiles.index(profile)
        self._profiles.remove(profile)
        self._profileCombo.blockSignals(True)
        self._profileCombo.takeItem(index)
        self._profileCombo.blockSignals(False)

    def restoreSettings(self, settings):
        """
        Restores settings from the application.
        
        :param      settings | <QSettings>
        """
        settings.beginGroup(self.objectName())

        curr_prof = None
        curr_name = qt.unwrapVariant(settings.value('current'))

        profiles = []
        for prof_name in settings.childGroups():
            settings.beginGroup(prof_name)

            prof_str = qt.unwrapVariant(settings.value('profile'))
            profile = XViewProfile.fromString(prof_str)
            profile.setName(prof_name)

            if (prof_name == curr_name):
                curr_prof = profile

            profiles.append(profile)

            settings.endGroup()

        self.blockSignals(True)
        self._profileCombo.blockSignals(True)
        self.setProfiles(profiles)

        if (curr_prof):
            self.setCurrentProfile(curr_prof)

        self._profileCombo.blockSignals(False)
        self.blockSignals(False)

        settings.endGroup()

    def saveSettings(self, settings):
        """
        Saves the settings for this widget to the application
        
        :param      settings | <QSettings>
        """
        settings.beginGroup(self.objectName())

        curr_prof = self.currentProfile()
        if (curr_prof):
            settings.setValue('current', curr_prof.name())

        for profile in self.profiles():
            settings.beginGroup(profile.name())
            settings.setValue('profile', qt.wrapVariant(profile.toString()))
            settings.endGroup()

        settings.endGroup()

    def setCurrentProfile(self, profile):
        """
        Sets the current profile to the inputed profile.
        
        :param      profile | <XViewProfile>
        """
        try:
            index = self._profiles.index(profile)
        except ValueError:
            index = -1

        self._profileCombo.setCurrentIndex(index)

    def setOptionsMenuPolicy(self, menuPolicy):
        """
        Sets the options menu policy for this item.
        
        :param      menuPolicy | <Qt.MenuPolicy>
        """
        self._optionsMenuPolicy = menuPolicy

    def setProfiles(self, profiles):
        """
        Sets a list of profiles to be the options for the manager.
        
        :param      profiles | [<XViewProfile>, ..]
        """
        self.blockSignals(True)
        self._profileCombo.blockSignals(True)

        self._profiles = profiles[:]
        self._profileCombo.clear()
        self._profileCombo.addItems(map(lambda x: x.name(), profiles))

        self._profileCombo.blockSignals(False)
        self.blockSignals(False)

    def setViewWidget(self, viewWidget):
        """
        Sets the view widget instance linked with this manager.
        
        :param      viewWidget | <XViewWidget>
        """
        self._viewWidget = viewWidget

    def showOptionsMenu(self):
        """
        Displays the options menu.  If the option menu policy is set to 
        CustomContextMenu, then the optionMenuRequested signal will be emitted,
        otherwise the default context menu will be displayed.
        """
        point = QPoint(0, self._optionsButton.height())
        global_point = self._optionsButton.mapToGlobal(point)

        # prompt the custom context menu
        if (self.optionsMenuPolicy() == Qt.CustomContextMenu):
            if (not self.signalsBlocked()):
                self.optionsMenuRequested.emit(global_point)
            return

        # use the default context menu
        menu = XViewProfileManagerMenu(self)
        menu.exec_(global_point)

    def viewWidget(self):
        """
        Returns the view widget that is associated with this manager.
        
        :return     <XViewWidget>
        """
        return self._viewWidget
Exemplo n.º 13
0
class Thermocouple(PluginBase):
    qtcb_error_state = pyqtSignal(bool, bool)

    def __init__(self, *args):
        PluginBase.__init__(self, BrickletThermocouple, *args)

        self.thermo = self.device

        self.qtcb_error_state.connect(self.cb_error_state)
        self.thermo.register_callback(self.thermo.CALLBACK_ERROR_STATE,
                                      self.qtcb_error_state.emit)

        self.cbe_temperature = CallbackEmulator(self.thermo.get_temperature,
                                                self.cb_temperature,
                                                self.increase_error_count)

        self.current_temperature = None # float, °C

        self.error_label = QLabel('Current Errors: None')
        self.error_label.setAlignment(Qt.AlignVCenter | Qt.AlignRight)

        plots = [('Temperature', Qt.red, lambda: self.current_temperature, u'{:.2f} °C'.format)]
        self.plot_widget = PlotWidget(u'Temperature [°C]', plots, extra_key_widgets=[self.error_label])

        self.averaging_label = QLabel('Averaging:')
        self.averaging_combo = QComboBox()
        self.averaging_combo.addItem('1', BrickletThermocouple.AVERAGING_1)
        self.averaging_combo.addItem('2', BrickletThermocouple.AVERAGING_2)
        self.averaging_combo.addItem('4', BrickletThermocouple.AVERAGING_4)
        self.averaging_combo.addItem('8', BrickletThermocouple.AVERAGING_8)
        self.averaging_combo.addItem('16', BrickletThermocouple.AVERAGING_16)

        self.type_label = QLabel('Thermocouple Type:')
        self.type_combo = QComboBox()
        self.type_combo.addItem('B', BrickletThermocouple.TYPE_B)
        self.type_combo.addItem('E', BrickletThermocouple.TYPE_E)
        self.type_combo.addItem('J', BrickletThermocouple.TYPE_J)
        self.type_combo.addItem('K', BrickletThermocouple.TYPE_K)
        self.type_combo.addItem('N', BrickletThermocouple.TYPE_N)
        self.type_combo.addItem('R', BrickletThermocouple.TYPE_R)
        self.type_combo.addItem('S', BrickletThermocouple.TYPE_S)
        self.type_combo.addItem('T', BrickletThermocouple.TYPE_T)
        self.type_combo.addItem('Gain 8', BrickletThermocouple.TYPE_G8)
        self.type_combo.addItem('Gain 32', BrickletThermocouple.TYPE_G32)

        self.filter_label = QLabel('Noise Rejection Filter:')
        self.filter_combo = QComboBox()
        self.filter_combo.addItem('50 Hz', BrickletThermocouple.FILTER_OPTION_50HZ)
        self.filter_combo.addItem('60 Hz', BrickletThermocouple.FILTER_OPTION_60HZ)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.averaging_label)
        hlayout.addWidget(self.averaging_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.type_label)
        hlayout.addWidget(self.type_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.filter_label)
        hlayout.addWidget(self.filter_combo)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(hlayout)

        self.averaging_combo.currentIndexChanged.connect(self.configuration_changed)
        self.type_combo.currentIndexChanged.connect(self.configuration_changed)
        self.filter_combo.currentIndexChanged.connect(self.configuration_changed)

    def start(self):
        async_call(self.thermo.get_temperature, None, self.cb_temperature, self.increase_error_count)
        async_call(self.thermo.get_configuration, None, self.cb_configuration, self.increase_error_count)
        async_call(self.thermo.get_error_state, None, lambda e: self.cb_error_state(e.over_under, e.open_circuit))
        self.cbe_temperature.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_temperature.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    def get_url_part(self):
        return 'thermocouple'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletThermocouple.DEVICE_IDENTIFIER

    def get_current_value(self):
        return self.current_value

    def configuration_changed(self, _):
        conf_averaging = self.averaging_combo.itemData(self.averaging_combo.currentIndex())
        conf_type = self.type_combo.itemData(self.type_combo.currentIndex())
        conf_filter = self.filter_combo.itemData(self.filter_combo.currentIndex())

        self.thermo.set_configuration(conf_averaging, conf_type, conf_filter)

    def cb_temperature(self, temperature):
        self.current_temperature = temperature / 100.0

    def cb_configuration(self, conf):
        self.averaging_combo.blockSignals(True)
        self.averaging_combo.setCurrentIndex(self.averaging_combo.findData(conf.averaging))
        self.averaging_combo.blockSignals(False)

        self.type_combo.blockSignals(True)
        self.type_combo.setCurrentIndex(self.type_combo.findData(conf.thermocouple_type))
        self.type_combo.blockSignals(False)

        self.filter_combo.blockSignals(True)
        self.filter_combo.setCurrentIndex(self.filter_combo.findData(conf.filter))
        self.filter_combo.blockSignals(False)

    def cb_error_state(self, over_under, open_circuit):
        if over_under or open_circuit:
            text = 'Current Errors: '
            if over_under:
                text += 'Over/Under Voltage'
            if over_under and open_circuit:
                text += ' and '
            if open_circuit:
                text += 'Open Circuit\n(defective thermocouple or nothing connected)'

            self.error_label.setStyleSheet('QLabel { color : red }')
            self.error_label.setText(text)
        else:
            self.error_label.setStyleSheet('')
            self.error_label.setText('Current Errors: None')
Exemplo n.º 14
0
class PlotConfigPanel(QFrame):
    """A panel to interact with PlotConfig instances."""
    plot_marker_styles = ["", ".", ",", "o", "*", "s", "+", "x", "p", "h", "H", "D", "d"]
    plot_line_styles = ["", "-", "--", "-.", ":"]

    def __init__(self, plot_config):
        QFrame.__init__(self)
        self.plot_config = plot_config
        self.connect(plot_config.signal_handler, SIGNAL('plotConfigChanged(PlotConfig)'), self._fetchValues)

        layout = QFormLayout()
        layout.setRowWrapPolicy(QFormLayout.WrapLongRows)

        self.chk_visible = QCheckBox()
        layout.addRow("Visible:", self.chk_visible)
        self.connect(self.chk_visible, SIGNAL('stateChanged(int)'), self._setVisibleState)

        self.plot_linestyle = QComboBox()
        self.plot_linestyle.addItems(self.plot_line_styles)
        self.connect(self.plot_linestyle, SIGNAL("currentIndexChanged(QString)"), self._setLineStyle)
        layout.addRow("Line style:", self.plot_linestyle)

        self.plot_marker_style = QComboBox()
        self.plot_marker_style.addItems(self.plot_marker_styles)
        self.connect(self.plot_marker_style, SIGNAL("currentIndexChanged(QString)"), self._setMarker)
        layout.addRow("Marker style:", self.plot_marker_style)



        self.alpha_spinner = QDoubleSpinBox(self)
        self.alpha_spinner.setMinimum(0.0)
        self.alpha_spinner.setMaximum(1.0)
        self.alpha_spinner.setDecimals(3)
        self.alpha_spinner.setSingleStep(0.01)

        self.connect(self.alpha_spinner, SIGNAL('valueChanged(double)'), self._setAlpha)
        layout.addRow("Blend factor:", self.alpha_spinner)

        self.color_picker = ColorPicker(plot_config)
        layout.addRow("Color:", self.color_picker)

        self.setLayout(layout)
        self._fetchValues(plot_config)

    def _fetchValues(self, plot_config):
        """Fetch values from a PlotConfig and insert into the panel."""
        self.plot_config = plot_config

        #block signals to avoid updating the incoming plot_config 

        state = self.plot_linestyle.blockSignals(True)
        linestyle_index = self.plot_line_styles.index(self.plot_config.linestyle)
        self.plot_linestyle.setCurrentIndex(linestyle_index)
        self.plot_linestyle.blockSignals(state)

        state = self.plot_marker_style.blockSignals(True)
        marker_index = self.plot_marker_styles.index(self.plot_config.marker)
        self.plot_marker_style.setCurrentIndex(marker_index)
        self.plot_marker_style.blockSignals(state)

        state = self.alpha_spinner.blockSignals(True)
        self.alpha_spinner.setValue(self.plot_config.alpha)
        self.alpha_spinner.blockSignals(state)

        state = self.chk_visible.blockSignals(True)
        self.chk_visible.setChecked(self.plot_config.is_visible)
        self.chk_visible.blockSignals(state)

        self.color_picker.update()

    #-------------------------------------------
    # update plot config from widgets
    #-------------------------------------------
    def _setLineStyle(self, linestyle):
        self.plot_config.linestyle = linestyle

    def _setMarker(self, marker):
        self.plot_config.marker = marker

    def _setAlpha(self, alpha):
        self.plot_config.alpha = alpha

    def _setVisibleState(self, state):
        self.plot_config.is_visible = state == 2
Exemplo n.º 15
0
class SchemeSelector(QWidget):
    
    currentChanged = pyqtSignal()
    changed = pyqtSignal()
    
    def __init__(self, parent=None):
        super(SchemeSelector, self).__init__(parent)
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)
        
        self.label = QLabel()
        self.scheme = QComboBox()
        self.menuButton = QPushButton(flat=True)
        menu = QMenu(self.menuButton)
        self.menuButton.setMenu(menu)
        layout.addWidget(self.label)
        layout.addWidget(self.scheme)
        layout.addWidget(self.menuButton)
        layout.addStretch(1)
        # action generator
        def act(slot, icon=None):
            a = QAction(self, triggered=slot)
            self.addAction(a)
            icon and a.setIcon(icons.get(icon))
            return a
        
        # add action
        a = self.addAction_ = act(self.slotAdd, 'list-add')
        menu.addAction(a)
        
        # remove action
        a = self.removeAction = act(self.slotRemove, 'list-remove')
        menu.addAction(a)
        
       
        # rename action
        a = self.renameAction = act(self.slotRename, 'document-edit')
        menu.addAction(a)
        
        menu.addSeparator()
        
        # import action
        a = self.importAction = act(self.slotImport, 'document-open')
        menu.addAction(a)
        
        # export action
        a = self.exportAction = act(self.slotExport, 'document-save-as')
        menu.addAction(a)
        
        
        self.scheme.currentIndexChanged.connect(self.slotSchemeChanged)
        app.translateUI(self)
        
    def translateUI(self):
        self.label.setText(_("Scheme:"))
        self.menuButton.setText(_("&Menu"))
        self.addAction_.setText(_("&Add..."))
        self.removeAction.setText(_("&Remove"))
        self.renameAction.setText(_("Re&name..."))
        self.importAction.setText(_("&Import..."))
        self.exportAction.setText(_("&Export..."))
        
    def slotSchemeChanged(self, index):
        """Called when the Scheme combobox is changed by the user."""
        self.disableDefault(self.scheme.itemData(index) == 'default')
        self.currentChanged.emit()
        self.changed.emit()
    
    def disableDefault(self, val):
        self.removeAction.setDisabled(val)
        self.renameAction.setDisabled(val)
    
    def schemes(self):
        """Returns the list with internal names of currently available schemes."""
        return [self.scheme.itemData(i) for i in range(self.scheme.count())]
        
    def currentScheme(self):
        """Returns the internal name of the currently selected scheme"""
        return self.scheme.itemData(self.scheme.currentIndex())
        
    def insertSchemeItem(self, name, scheme):
        for i in range(1, self.scheme.count()):
            n = self.scheme.itemText(i)
            if n.lower() > name.lower():
                self.scheme.insertItem(i, name, scheme)
                break
        else:
            self.scheme.addItem(name, scheme)
    
    def addScheme(self, name):
        num, key = 1, 'user1'
        while key in self.schemes() or key in self._schemesToRemove:
            num += 1
            key = 'user{0}'.format(num)
        self.insertSchemeItem(name, key)
        self.scheme.setCurrentIndex(self.scheme.findData(key))
        return key
    
    def slotAdd(self):
        name, ok = QInputDialog.getText(self,
            app.caption(_("Add Scheme")),
            _("Please enter a name for the new scheme:"))
        if ok:
            self.addScheme(name)
        
    
    def slotRemove(self):
        index = self.scheme.currentIndex()
        scheme = self.scheme.itemData(index)
        if scheme == 'default':
            return # default can not be removed
        
        self._schemesToRemove.add(scheme)
        self.scheme.removeItem(index)
    
    def slotRename(self):
        index = self.scheme.currentIndex()
        name = self.scheme.itemText(index)
        scheme = self.scheme.itemData(index)
        newName, ok = QInputDialog.getText(self, _("Rename"), _("New name:"), text=name)
        if ok:
            self.scheme.blockSignals(True)
            self.scheme.removeItem(index)
            self.insertSchemeItem(newName, scheme)
            self.scheme.setCurrentIndex(self.scheme.findData(scheme))
            self.scheme.blockSignals(False)
            self.changed.emit()
           
    def slotImport(self):
        filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files"))
        caption = app.caption(_("dialog title", "Import color theme"))
        filename = QFileDialog.getOpenFileName(self, caption, os.environ['HOME'], filetypes)
        if filename:
            self.parent().import_(filename)
    
    def slotExport(self):
        name = self.scheme.currentText()
        filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files"))
        caption = app.caption(_("dialog title",
            "Export {name}").format(name=name))
        path = os.path.join(os.environ['HOME'], name+'.xml')
        filename = QFileDialog.getSaveFileName(self, caption, path, filetypes)
        if filename:
            if os.path.splitext(filename)[1] != '.xml':
                filename += '.xml'
            self.parent().export(name, filename)
            
    
    def loadSettings(self, currentKey, namesGroup):
        # dont mark schemes for removal anymore
        self._schemesToRemove = set()
        
        s = QSettings()
        cur = s.value(currentKey, "default", type(""))
        
        # load the names for the shortcut schemes
        s.beginGroup(namesGroup)
        self.scheme.clear()
        self.scheme.addItem(_("Default"), "default")
        lst = [(s.value(key, key, type("")), key) for key in s.childKeys()]
        for name, key in sorted(lst, key=lambda f: f[0].lower()):
            self.scheme.addItem(name, key)
        block = self.scheme.blockSignals(True)
        
        # find out index
        index = self.scheme.findData(cur)
        self.disableDefault(cur == 'default')
        self.scheme.setCurrentIndex(index)
        self.scheme.blockSignals(block)
        self.currentChanged.emit()
        
    def saveSettings(self, currentKey, namesGroup, removePrefix=None):
        # first save new scheme names
        s = QSettings()
        s.beginGroup(namesGroup)
        for i in range(self.scheme.count()):
            if self.scheme.itemData(i) != 'default':
                s.setValue(self.scheme.itemData(i), self.scheme.itemText(i))
        
        for scheme in self._schemesToRemove:
            s.remove(scheme)
        s.endGroup()
        if removePrefix:
            for scheme in self._schemesToRemove:
                s.remove("{0}/{1}".format(removePrefix, scheme))
        # then save current
        scheme = self.currentScheme()
        s.setValue(currentKey, scheme)
        # clean up
        self._schemesToRemove = set()
Exemplo n.º 16
0
class MotorizedLinearPoti(COMCUPluginBase):
    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletMotorizedLinearPoti, *args)

        self.mp = self.device

        self.cbe_position = CallbackEmulator(self.mp.get_position,
                                             self.cb_position,
                                             self.increase_error_count)

        self.current_position = None

        self.slider = QSlider(Qt.Horizontal)
        self.slider.setRange(0, 100)
        self.slider.setMinimumWidth(200)
        self.slider.setEnabled(False)

        plots = [('Potentiometer Position', Qt.red, lambda: self.current_position, str)]
        self.plot_widget = PlotWidget('Position', plots, extra_key_widgets=[self.slider],
                                      curve_motion_granularity=40, update_interval=0.025)

        self.motor_slider = QSlider(Qt.Horizontal)
        self.motor_slider.setRange(0, 100)
        self.motor_slider.valueChanged.connect(self.motor_slider_value_changed)
        self.motor_hold_position = QCheckBox("Hold Position")
        self.motor_drive_mode = QComboBox()
        self.motor_drive_mode.addItem('Fast')
        self.motor_drive_mode.addItem('Smooth')
        
        def get_motor_slider_value():
            return self.motor_slider.value()
        
        self.motor_hold_position.stateChanged.connect(lambda x: self.motor_slider_value_changed(get_motor_slider_value()))
        self.motor_drive_mode.currentIndexChanged.connect(lambda x: self.motor_slider_value_changed(get_motor_slider_value()))

        self.motor_position_label = MotorPositionLabel('Motor Target Position:')

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.motor_position_label)
        hlayout.addWidget(self.motor_slider)
        hlayout.addWidget(self.motor_drive_mode)
        hlayout.addWidget(self.motor_hold_position)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(hlayout)

    def start(self):
        async_call(self.mp.get_position, None, self.cb_position, self.increase_error_count)
        async_call(self.mp.get_motor_position, None, self.cb_motor_position, self.increase_error_count)

        self.cbe_position.set_period(25)
        self.plot_widget.stop = False

    def stop(self):
        self.cbe_position.set_period(0)
        self.plot_widget.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletMotorizedLinearPoti.DEVICE_IDENTIFIER

    def cb_position(self, position):
        self.current_position = position
        self.slider.setValue(position)

    def cb_motor_position(self, motor):
        self.motor_slider.blockSignals(True)
        self.motor_hold_position.blockSignals(True)
        self.motor_drive_mode.blockSignals(True)

        self.motor_hold_position.setChecked(motor.hold_position)
        self.motor_drive_mode.setCurrentIndex(motor.drive_mode)
        self.motor_position_label.setText(str(motor.position))
        self.motor_slider.setValue(motor.position)

        self.motor_slider.blockSignals(False)
        self.motor_hold_position.blockSignals(False)
        self.motor_drive_mode.blockSignals(False)

    
    def motor_slider_value_changed(self, position):
        self.motor_position_label.setText(str(position))
        self.mp.set_motor_position(self.motor_slider.value(), self.motor_drive_mode.currentIndex(), self.motor_hold_position.isChecked())
Exemplo n.º 17
0
class DistanceIRV2(COMCUPluginBase):
    NUM_VALUES = 512
    DIVIDER = 2**12/NUM_VALUES

    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletDistanceIRV2, *args)

        self.dist = self.device

        self.cbe_distance = CallbackEmulator(self.dist.get_distance,
                                             self.cb_distance,
                                             self.increase_error_count)
        self.cbe_analog_value = CallbackEmulator(self.dist.get_analog_value,
                                                 self.cb_analog_value,
                                                 self.increase_error_count)

        self.analog_label = AnalogLabel('Analog Value:')
        hlayout = QHBoxLayout()
        self.average_label = QLabel('Moving Average Length:')
        self.average_spin = QSpinBox()
        self.average_spin.setMinimum(1)
        self.average_spin.setMaximum(1000)
        self.average_spin.setSingleStep(1)
        self.average_spin.setValue(25)
        self.average_spin.editingFinished.connect(self.average_spin_finished)

        self.sensor_label = QLabel('Sensor Type:')
        self.sensor_combo = QComboBox()
        self.sensor_combo.addItem('2Y0A41 (4-30cm)')
        self.sensor_combo.addItem('2Y0A21 (10-80cm)')
        self.sensor_combo.addItem('2Y0A02 (20-150cm)')
        self.sensor_combo.currentIndexChanged.connect(self.sensor_combo_changed)

        hlayout.addWidget(self.average_label)
        hlayout.addWidget(self.average_spin)
        hlayout.addStretch()
        hlayout.addWidget(self.sensor_label)
        hlayout.addWidget(self.sensor_combo)

        self.current_distance = None # float, cm

        plots = [('Distance', Qt.red, lambda: self.current_distance, '{} cm'.format)]
        self.plot_widget = PlotWidget('Distance [cm]', plots, extra_key_widgets=[self.analog_label])

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(hlayout)

    def sensor_combo_changed(self, index):
        self.dist.set_sensor_type(index)

    def average_spin_finished(self):
        self.dist.set_moving_average_configuration(self.average_spin.value())

    def cb_moving_average_configuration(self, average):
        self.average_spin.blockSignals(True)
        self.average_spin.setValue(average)
        self.average_spin.blockSignals(False)

    def cb_sensor_type(self, sensor):
        self.sensor_combo.blockSignals(True)
        self.sensor_combo.setCurrentIndex(sensor)
        self.sensor_combo.blockSignals(False)

    def start(self):
        async_call(self.dist.get_moving_average_configuration, None, self.cb_moving_average_configuration, self.increase_error_count)
        async_call(self.dist.get_sensor_type, None, self.cb_sensor_type, self.increase_error_count)
        async_call(self.dist.get_distance, None, self.cb_distance, self.increase_error_count)
        self.cbe_distance.set_period(10)
        self.cbe_analog_value.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_distance.set_period(0)
        self.cbe_analog_value.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletDistanceIRV2.DEVICE_IDENTIFIER

    def cb_distance(self, distance):
        self.current_distance = distance / 10.0

    def cb_analog_value(self, analog_value):
        self.analog_label.setText(analog_value)