class QgsTextAnnotationDialog(QDialog):
    def __init__(self, item):
        QDialog.__init__(self)
        self.gridLayout = QGridLayout(self)
        self.gridLayout.setObjectName(("gridLayout"))
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName(("horizontalLayout"))
        self.mFontComboBox = QFontComboBox(self)
        self.mFontComboBox.setObjectName(("mFontComboBox"))
        self.horizontalLayout.addWidget(self.mFontComboBox)
        spacerItem = QSpacerItem(38, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.mFontSizeSpinBox = QSpinBox(self)
        self.mFontSizeSpinBox.setObjectName(("mFontSizeSpinBox"))
        self.horizontalLayout.addWidget(self.mFontSizeSpinBox)
        self.mBoldPushButton = QPushButton(self)
        self.mBoldPushButton.setMinimumSize(QSize(50, 0))
        self.mBoldPushButton.setCheckable(True)
        self.mBoldPushButton.setObjectName(("mBoldPushButton"))
        self.horizontalLayout.addWidget(self.mBoldPushButton)
        self.mItalicsPushButton = QPushButton(self)
        self.mItalicsPushButton.setMinimumSize(QSize(50, 0))
        self.mItalicsPushButton.setCheckable(True)
        self.mItalicsPushButton.setObjectName(("mItalicsPushButton"))
        self.horizontalLayout.addWidget(self.mItalicsPushButton)
        self.mFontColorButton = QgsColorButton(self)
        self.mFontColorButton.setText((""))
        self.mFontColorButton.setAutoDefault(False)
        self.mFontColorButton.setObjectName(("mFontColorButton"))
        self.horizontalLayout.addWidget(self.mFontColorButton)
        self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
        self.mButtonBox = QDialogButtonBox(self)
        self.mButtonBox.setOrientation(Qt.Horizontal)
        self.mButtonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
        self.mButtonBox.setObjectName(("mButtonBox"))
        self.gridLayout.addWidget(self.mButtonBox, 3, 0, 1, 1)
        self.mTextEdit = QTextEdit(self)
        self.mTextEdit.setObjectName(("mTextEdit"))
        self.gridLayout.addWidget(self.mTextEdit, 1, 0, 1, 1)
        self.mStackedWidget = QStackedWidget(self)
        self.mStackedWidget.setObjectName(("mStackedWidget"))
        self.page = QWidget()
        self.page.setObjectName(("page"))
        self.mStackedWidget.addWidget(self.page)
        self.page_2 = QWidget()
        self.page_2.setObjectName(("page_2"))
        self.mStackedWidget.addWidget(self.page_2)
        self.gridLayout.addWidget(self.mStackedWidget, 2, 0, 1, 1)
        self.setLayout(self.gridLayout)
        
        self.mStackedWidget.setCurrentIndex(0)
        QObject.connect(self.mButtonBox, SIGNAL(("accepted()")), self.accept)
        QObject.connect(self.mButtonBox, SIGNAL(("rejected()")), self.reject)
        
        self.setTabOrder(self.mFontComboBox, self.mFontSizeSpinBox)
        self.setTabOrder(self.mFontSizeSpinBox, self.mBoldPushButton)
        self.setTabOrder(self.mBoldPushButton, self.mItalicsPushButton)
        self.setTabOrder(self.mItalicsPushButton, self.mFontColorButton)
        self.setTabOrder(self.mFontColorButton, self.mTextEdit)
        self.setTabOrder(self.mTextEdit, self.mButtonBox)
        
        self.setWindowTitle("Annotation text")
        self.mBoldPushButton.setText("B")
        self.mItalicsPushButton.setText("I")
        
        self.mTextDocument = None
        self.mItem = item
        self.mEmbeddedWidget = QgsAnnotationWidget(self, self.mItem )
        self.mEmbeddedWidget.show()
        self.mStackedWidget.addWidget( self.mEmbeddedWidget )
        self.mStackedWidget.setCurrentWidget( self.mEmbeddedWidget )
        if ( self.mItem != None ):
            self.mTextDocument = self.mItem.document()
            self.mTextEdit.setDocument( self.mTextDocument )
        self.mFontColorButton.setColorDialogTitle(  "Select font color"  )
        self.mFontColorButton.setColorDialogOptions( QColorDialog.ShowAlphaChannel )
        self.setCurrentFontPropertiesToGui()
        QObject.connect( self.mButtonBox, SIGNAL("accepted()"), self.applyTextToItem)
#         QObject.connect( self.mFontComboBox, SIGNAL( "currentFontChanged(QFont())"), self.changeCurrentFormat)
        self.mFontComboBox.currentFontChanged.connect(self.changeCurrentFormat)
        QObject.connect( self.mFontSizeSpinBox, SIGNAL( "valueChanged( int )" ), self.changeCurrentFormat ) 
        QObject.connect( self.mBoldPushButton, SIGNAL( "toggled( bool )" ), self.changeCurrentFormat)
        QObject.connect( self.mItalicsPushButton, SIGNAL( "toggled( bool )" ), self.changeCurrentFormat)
        QObject.connect( self.mTextEdit, SIGNAL( "cursorPositionChanged()" ), self.setCurrentFontPropertiesToGui )
        
#         QObject.connect( self.mButtonBox, SIGNAL( "accepted()" ), self.applySettingsToItem)
        deleteButton = QPushButton( "Delete" )
        QObject.connect( deleteButton, SIGNAL( "clicked()" ), self.deleteItem )
        self.mButtonBox.addButton( deleteButton, QDialogButtonBox.RejectRole )
    def applyTextToItem(self):
        if ( self.mItem  != None and self.mTextDocument !=None ):
            if ( self.mEmbeddedWidget != None):
                self.mEmbeddedWidget.apply()
            self.mItem.setDocument( self.mTextDocument )
            self.mItem.update()
    def changeCurrentFormat(self):
        newFont = QFont()
        newFont.setFamily( self.mFontComboBox.currentFont().family() )
        #bold
        if ( self.mBoldPushButton.isChecked() ):
            newFont.setBold( True )
        else:
            newFont.setBold( False )
        #italic
        if ( self.mItalicsPushButton.isChecked() ):
            newFont.setItalic( True )
        else:
            newFont.setItalic( False )
        #size
        newFont.setPointSize( self.mFontSizeSpinBox.value() )
        self.mTextEdit.setCurrentFont( newFont )
        #color
        self.mTextEdit.setTextColor( self.mFontColorButton.color() )
        
    def on_mFontColorButton_colorChanged(self, color ):
        self.changeCurrentFormat()
    def setCurrentFontPropertiesToGui(self):
        self.blockAllSignals( True )
        currentFont = self.mTextEdit.currentFont()
        self.mFontComboBox.setCurrentFont( currentFont )
        self.mFontSizeSpinBox.setValue( currentFont.pointSize() )
        self.mBoldPushButton.setChecked( currentFont.bold() )
        self.mItalicsPushButton.setChecked( currentFont.italic() )
        self.mFontColorButton.setColor( self.mTextEdit.textColor() )
        self.blockAllSignals( False )
        
    def blockAllSignals(self, block ):
        self.mFontComboBox.blockSignals( block )
        self.mFontSizeSpinBox.blockSignals( block )
        self.mBoldPushButton.blockSignals( block )
        self.mItalicsPushButton.blockSignals( block )
        self.mFontColorButton.blockSignals( block )
    
    def deleteItem(self):
        scene = self.mItem.scene()
        if ( scene != None ):
            scene.removeItem( self.mItem )
        self.mItem = None
Example #2
0
class LaserRangeFinder(PluginBase):
    def __init__(self, *args):
        PluginBase.__init__(self, BrickletLaserRangeFinder, *args)

        self.lrf = self.device

        self.cbe_distance = CallbackEmulator(self.lrf.get_distance,
                                             self.cb_distance,
                                             self.increase_error_count)
        self.cbe_velocity = CallbackEmulator(self.lrf.get_velocity,
                                             self.cb_velocity,
                                             self.increase_error_count)

        self.current_distance = None  # int, cm
        self.current_velocity = None  # float, m/s

        plots_distance = [('Distance', Qt.red, lambda: self.current_distance,
                           format_distance)]
        plots_velocity = [('Velocity', Qt.red, lambda: self.current_velocity,
                           '{:.2f} m/s'.format)]
        self.plot_widget_distance = PlotWidget('Distance [cm]', plots_distance)
        self.plot_widget_velocity = PlotWidget('Velocity [m/s]',
                                               plots_velocity)

        self.mode_label = QLabel('Mode:')
        self.mode_combo = QComboBox()
        self.mode_combo.addItem("Distance: 1cm resolution, 40m max")
        self.mode_combo.addItem("Velocity: 0.10 m/s resolution, 12.70m/s max")
        self.mode_combo.addItem("Velocity: 0.25 m/s resolution, 31.75m/s max")
        self.mode_combo.addItem("Velocity: 0.50 m/s resolution, 63.50m/s max")
        self.mode_combo.addItem("Velocity: 1.00 m/s resolution, 127.00m/s max")
        self.mode_combo.currentIndexChanged.connect(self.mode_changed)
        self.mode_combo.hide()

        self.label_average_distance = QLabel('Moving Average for Distance:')

        self.spin_average_distance = QSpinBox()
        self.spin_average_distance.setMinimum(0)
        self.spin_average_distance.setMaximum(50)
        self.spin_average_distance.setSingleStep(1)
        self.spin_average_distance.setValue(10)
        self.spin_average_distance.editingFinished.connect(
            self.spin_average_finished)

        self.label_average_velocity = QLabel('Moving Average for Velocity:')

        self.spin_average_velocity = QSpinBox()
        self.spin_average_velocity.setMinimum(0)
        self.spin_average_velocity.setMaximum(50)
        self.spin_average_velocity.setSingleStep(1)
        self.spin_average_velocity.setValue(10)
        self.spin_average_velocity.editingFinished.connect(
            self.spin_average_finished)

        self.enable_laser = QCheckBox("Enable Laser")
        self.enable_laser.stateChanged.connect(self.enable_laser_changed)

        self.label_acquisition_count = QLabel('Acquisition Count:')
        self.spin_acquisition_count = QSpinBox()
        self.spin_acquisition_count.setMinimum(1)
        self.spin_acquisition_count.setMaximum(255)
        self.spin_acquisition_count.setSingleStep(1)
        self.spin_acquisition_count.setValue(128)

        self.enable_qick_termination = QCheckBox("Quick Termination")

        self.label_threshold = QLabel('Threshold:')
        self.threshold = QCheckBox("Automatic Threshold")

        self.spin_threshold = QSpinBox()
        self.spin_threshold.setMinimum(1)
        self.spin_threshold.setMaximum(255)
        self.spin_threshold.setSingleStep(1)
        self.spin_threshold.setValue(1)

        self.label_frequency = QLabel('Frequency [Hz]:')
        self.frequency = QCheckBox(
            "Automatic Frequency (Disable for Velocity)")

        self.spin_frequency = QSpinBox()
        self.spin_frequency.setMinimum(10)
        self.spin_frequency.setMaximum(500)
        self.spin_frequency.setSingleStep(1)
        self.spin_frequency.setValue(10)

        self.spin_acquisition_count.editingFinished.connect(
            self.configuration_changed)
        self.enable_qick_termination.stateChanged.connect(
            self.configuration_changed)
        self.spin_threshold.editingFinished.connect(self.configuration_changed)
        self.threshold.stateChanged.connect(self.configuration_changed)
        self.spin_frequency.editingFinished.connect(self.configuration_changed)
        self.frequency.stateChanged.connect(self.configuration_changed)

        layout_h1 = QHBoxLayout()
        layout_h1.addWidget(self.plot_widget_distance)
        layout_h1.addWidget(self.plot_widget_velocity)

        layout_h2 = QHBoxLayout()
        layout_h2.addWidget(self.mode_label)
        layout_h2.addWidget(self.mode_combo)
        layout_h2.addWidget(self.label_average_distance)
        layout_h2.addWidget(self.spin_average_distance)
        layout_h2.addWidget(self.label_average_velocity)
        layout_h2.addWidget(self.spin_average_velocity)
        layout_h2.addStretch()
        layout_h2.addWidget(self.enable_laser)

        layout_h3 = QHBoxLayout()
        layout_h3.addWidget(self.label_frequency)
        layout_h3.addWidget(self.spin_frequency)
        layout_h3.addWidget(self.frequency)
        layout_h3.addStretch()
        layout_h3.addWidget(self.enable_qick_termination)

        layout_h4 = QHBoxLayout()
        layout_h4.addWidget(self.label_threshold)
        layout_h4.addWidget(self.spin_threshold)
        layout_h4.addWidget(self.threshold)
        layout_h4.addStretch()
        layout_h4.addWidget(self.label_acquisition_count)
        layout_h4.addWidget(self.spin_acquisition_count)

        self.widgets_distance = [
            self.plot_widget_distance, self.spin_average_distance,
            self.label_average_distance
        ]
        self.widgets_velocity = [
            self.plot_widget_velocity, self.spin_average_velocity,
            self.label_average_velocity
        ]

        for w in self.widgets_distance:
            w.hide()
        for w in self.widgets_velocity:
            w.hide()

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

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h1)
        layout.addWidget(line)
        layout.addLayout(layout_h2)
        layout.addLayout(layout_h3)
        layout.addLayout(layout_h4)

        self.has_sensor_hardware_version_api = self.firmware_version >= (2, 0,
                                                                         3)
        self.has_configuration_api = self.firmware_version >= (2, 0, 3)

    def start(self):
        if self.has_sensor_hardware_version_api:
            async_call(self.lrf.get_sensor_hardware_version, None,
                       self.get_sensor_hardware_version_async,
                       self.increase_error_count)
        else:
            self.get_sensor_hardware_version_async(1)

        if self.has_configuration_api:
            async_call(self.lrf.get_configuration, None,
                       self.get_configuration_async, self.increase_error_count)

        async_call(self.lrf.get_mode, None, self.get_mode_async,
                   self.increase_error_count)
        async_call(self.lrf.is_laser_enabled, None,
                   self.is_laser_enabled_async, self.increase_error_count)
        async_call(self.lrf.get_moving_average, None,
                   self.get_moving_average_async, self.increase_error_count)
        async_call(self.lrf.get_distance, None, self.cb_distance,
                   self.increase_error_count)
        async_call(self.lrf.get_velocity, None, self.cb_velocity,
                   self.increase_error_count)
        self.cbe_distance.set_period(25)
        self.cbe_velocity.set_period(25)

        self.plot_widget_distance.stop = False
        self.plot_widget_velocity.stop = False

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

        self.plot_widget_distance.stop = True
        self.plot_widget_velocity.stop = True

    def destroy(self):
        pass

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

    def is_laser_enabled_async(self, enabled):
        if enabled:
            self.enable_laser.setChecked(True)
        else:
            self.enable_laser.setChecked(False)

    def enable_laser_changed(self, state):
        if state == Qt.Checked:
            self.lrf.enable_laser()
        else:
            self.lrf.disable_laser()

    def mode_changed(self, value):
        if value < 0 or value > 4:
            return

        self.lrf.set_mode(value)
        if value == 0:
            for w in self.widgets_velocity:
                w.hide()
            for w in self.widgets_distance:
                w.show()
        else:
            for w in self.widgets_distance:
                w.hide()
            for w in self.widgets_velocity:
                w.show()

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

    def cb_velocity(self, velocity):
        self.current_velocity = velocity / 100.0

    def configuration_changed(self):
        acquisition_count = self.spin_acquisition_count.value()
        enable_quick_termination = self.enable_qick_termination.isChecked()

        if self.threshold.isChecked():
            threshold = 0
        else:
            threshold = self.spin_threshold.value()

        if self.frequency.isChecked():
            frequency = 0
            for w in self.widgets_velocity:
                w.hide()
        else:
            frequency = self.spin_frequency.value()
            for w in self.widgets_velocity:
                w.show()

        self.spin_threshold.setDisabled(threshold == 0)
        self.spin_frequency.setDisabled(frequency == 0)

        self.lrf.set_configuration(acquisition_count, enable_quick_termination,
                                   threshold, frequency)

    def get_configuration_async(self, conf):
        self.spin_acquisition_count.blockSignals(True)
        self.spin_acquisition_count.setValue(conf.acquisition_count)
        self.spin_acquisition_count.blockSignals(False)

        self.enable_qick_termination.blockSignals(True)
        self.enable_qick_termination.setChecked(conf.enable_quick_termination)
        self.enable_qick_termination.blockSignals(False)

        self.spin_threshold.blockSignals(True)
        self.spin_threshold.setValue(conf.threshold_value)
        self.spin_threshold.setDisabled(conf.threshold_value == 0)
        self.spin_threshold.blockSignals(False)

        self.spin_frequency.blockSignals(True)
        self.spin_frequency.setValue(conf.measurement_frequency)
        self.spin_frequency.setDisabled(conf.measurement_frequency == 0)
        self.spin_frequency.blockSignals(False)

        self.threshold.blockSignals(True)
        self.threshold.setChecked(conf.threshold_value == 0)
        self.threshold.blockSignals(False)

        self.frequency.blockSignals(True)
        self.frequency.setChecked(conf.measurement_frequency == 0)
        self.frequency.blockSignals(False)

        self.configuration_changed()

    def get_sensor_hardware_version_async(self, value):
        if value == 1:
            self.mode_combo.show()
            self.mode_label.show()
            self.label_acquisition_count.hide()
            self.spin_acquisition_count.hide()
            self.enable_qick_termination.hide()
            self.label_threshold.hide()
            self.spin_threshold.hide()
            self.threshold.hide()
            self.label_frequency.hide()
            self.spin_frequency.hide()
            self.frequency.hide()
        else:
            self.mode_combo.hide()
            self.mode_label.hide()
            self.label_acquisition_count.show()
            self.spin_acquisition_count.show()
            self.enable_qick_termination.show()
            self.label_threshold.show()
            self.spin_threshold.show()
            self.threshold.show()
            self.label_frequency.show()
            self.spin_frequency.show()
            self.frequency.show()

            for w in self.widgets_distance:
                w.show()
            for w in self.widgets_velocity:
                w.show()

    def get_mode_async(self, value):
        self.mode_combo.setCurrentIndex(value)
        self.mode_changed(value)

    def get_moving_average_async(self, avg):
        self.spin_average_distance.setValue(avg.distance_average_length)
        self.spin_average_velocity.setValue(avg.velocity_average_length)

    def spin_average_finished(self):
        self.lrf.set_moving_average(self.spin_average_distance.value(),
                                    self.spin_average_velocity.value())
Example #3
0
class PlotWidget(QWidget):
    def __init__(self,
                 y_scale_title_text,
                 curve_configs,
                 clear_button='default',
                 parent=None,
                 scales_visible=True,
                 curve_outer_border_visible=True,
                 curve_motion_granularity=10,
                 canvas_color=QColor(245, 245, 245),
                 external_timer=None,
                 key='top-value',
                 extra_key_widgets=None,
                 update_interval=0.1,
                 curve_start='left',
                 moving_average_config=None,
                 x_scale_title_text='Time [s]',
                 x_diff=20,
                 x_scale_skip_last_tick=True):
        QWidget.__init__(self, parent)

        self.setMinimumSize(300, 250)

        self.stop = True
        self.curve_configs = [
            CurveConfig(*curve_config) for curve_config in curve_configs
        ]
        self.plot = Plot(self, x_scale_title_text, y_scale_title_text,
                         x_scale_skip_last_tick, self.curve_configs,
                         scales_visible, curve_outer_border_visible,
                         curve_motion_granularity, canvas_color, curve_start,
                         x_diff)
        self.set_x_scale = self.plot.set_x_scale
        self.set_fixed_y_scale = self.plot.set_fixed_y_scale
        self.key = key
        self.key_items = []
        self.key_has_values = key.endswith('-value') if key != None else False
        self.first_show = True
        self.timestamp = 0  # seconds
        self.update_interval = update_interval  # seconds

        h1layout = QHBoxLayout()
        h1layout.setContentsMargins(0, 0, 0, 0)
        h1layout_empty = True

        if clear_button == 'default':
            self.clear_button = QToolButton()
            self.clear_button.setText('Clear Graph')

            h1layout.addWidget(self.clear_button)
            h1layout.addStretch(1)
            h1layout_empty = False
        else:
            self.clear_button = clear_button

        if self.clear_button != None:
            self.clear_button.clicked.connect(self.clear_clicked)

        v1layout = None

        if self.key != None:
            if len(self.curve_configs) == 1:
                label = FixedSizeLabel(self)
                label.setText(self.curve_configs[0].title)

                self.key_items.append(label)
            else:
                for i, curve_config in enumerate(self.curve_configs):
                    pixmap = QPixmap(10, 2)
                    QPainter(pixmap).fillRect(0, 0, 10, 2, curve_config.color)

                    button = FixedSizeToolButton(self)
                    button.setText(curve_config.title)
                    button.setIcon(QIcon(pixmap))
                    button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
                    button.setCheckable(True)
                    button.setChecked(True)
                    button.toggled.connect(
                        functools.partial(self.plot.show_curve, i))

                    self.key_items.append(button)

            if self.key.startswith('top'):
                for key_item in self.key_items:
                    h1layout.addWidget(key_item)
                    h1layout_empty = False
            elif self.key.startswith('right'):
                v1layout = QVBoxLayout()
                v1layout.setContentsMargins(0, 0, 0, 0)
                v1layout.addSpacing(self.plot.get_legend_offset_y())

                for key_item in self.key_items:
                    v1layout.addWidget(key_item)

                v1layout.addStretch(1)

        if not h1layout_empty:
            h1layout.addStretch(1)

        if extra_key_widgets != None:
            if self.key == None or self.key.startswith('top'):
                for widget in extra_key_widgets:
                    h1layout.addWidget(widget)
                    h1layout_empty = False
            elif self.key.startswith('right'):
                if v1layout == None:
                    v1layout = QVBoxLayout()
                    v1layout.setContentsMargins(0, 0, 0, 0)
                    v1layout.addSpacing(self.plot.get_legend_offset_y())

                if self.key.startswith('top'):
                    for widget in extra_key_widgets:
                        v1layout.addWidget(widget)

        v2layout = QVBoxLayout(self)
        v2layout.setContentsMargins(0, 0, 0, 0)

        if not h1layout_empty:
            v2layout.addLayout(h1layout)

        if v1layout != None:
            h2layout = QHBoxLayout()
            h2layout.setContentsMargins(0, 0, 0, 0)

            h2layout.addWidget(self.plot)
            h2layout.addLayout(v1layout)

            v2layout.addLayout(h2layout)
        else:
            v2layout.addWidget(self.plot)

        self.moving_average_config = moving_average_config

        if moving_average_config != None:
            self.moving_average_label = QLabel('Moving Average Length:')
            self.moving_average_spinbox = QSpinBox()
            self.moving_average_spinbox.setMinimum(
                moving_average_config.min_length)
            self.moving_average_spinbox.setMaximum(
                moving_average_config.max_length)
            self.moving_average_spinbox.setSingleStep(1)

            self.moving_average_layout = QHBoxLayout()
            self.moving_average_layout.addStretch()
            self.moving_average_layout.addWidget(self.moving_average_label)
            self.moving_average_layout.addWidget(self.moving_average_spinbox)
            self.moving_average_layout.addStretch()

            self.moving_average_spinbox.valueChanged.connect(
                self.moving_average_spinbox_value_changed)

            v2layout.addLayout(self.moving_average_layout)

        if external_timer == None:
            self.timer = QTimer(self)
            self.timer.timeout.connect(self.add_new_data)
            self.timer.start(self.update_interval * 1000)
        else:
            # assuming that the external timer runs with the configured interval
            external_timer.timeout.connect(self.add_new_data)

    def set_moving_average_value(self, value):
        self.moving_average_spinbox.blockSignals(True)
        self.moving_average_spinbox.setValue(value)
        self.moving_average_spinbox.blockSignals(False)

    def get_moving_average_value(self):
        return self.moving_average_spinbox.value()

    def moving_average_spinbox_value_changed(self, value):
        if self.moving_average_config != None:
            if self.moving_average_config.callback != None:
                self.moving_average_config.callback(value)

    # overrides QWidget.showEvent
    def showEvent(self, event):
        QWidget.showEvent(self, event)

        if self.first_show:
            self.first_show = False

            if len(self.key_items) > 1 and self.key.startswith('right'):
                widths = []

                for key_item in self.key_items:
                    widths.append(key_item.width())

                width = max(widths)

                for key_item in self.key_items:
                    size = key_item.minimumSize()

                    size.setWidth(width)

                    key_item.setMinimumSize(size)

    def get_key_item(self, i):
        return self.key_items[i]

    def set_data(self, i, x, y):
        # FIXME: how to set potential key items from this?
        self.plot.set_data(i, x, y)

    # internal
    def add_new_data(self):
        if self.stop:
            return

        for i, curve_config in enumerate(self.curve_configs):
            value = curve_config.value_getter()

            if value != None:
                if len(self.key_items) > 0 and self.key_has_values:
                    self.key_items[i].setText(
                        curve_config.title + ': ' +
                        curve_config.value_formatter(value))

                self.plot.add_data(i, self.timestamp, value)
            elif len(self.key_items) > 0 and self.key_has_values:
                self.key_items[i].setText(curve_config.title)

        self.timestamp += self.update_interval

    # internal
    def clear_clicked(self):
        self.plot.clear_graph()
        self.counter = 0
Example #4
0
class XPagesWidget(QWidget):
    """ """
    currentPageChanged = Signal(int)
    pageSizeChanged = Signal(int)
    pageCountChanged = Signal(int)

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

        # define custom properties
        self._currentPage = 1
        self._pageCount = 10
        self._itemCount = 0
        self._pageSize = 50
        self._itemsTitle = 'items'

        self._pagesSpinner = QSpinBox()
        self._pagesSpinner.setMinimum(1)
        self._pagesSpinner.setMaximum(10)

        self._pageSizeCombo = XComboBox(self)
        self._pageSizeCombo.setHint('all')
        self._pageSizeCombo.addItems(['', '25', '50', '75', '100'])
        self._pageSizeCombo.setCurrentIndex(2)

        self._nextButton = QToolButton(self)
        self._nextButton.setAutoRaise(True)
        self._nextButton.setArrowType(Qt.RightArrow)
        self._nextButton.setFixedWidth(16)

        self._prevButton = QToolButton(self)
        self._prevButton.setAutoRaise(True)
        self._prevButton.setArrowType(Qt.LeftArrow)
        self._prevButton.setFixedWidth(16)
        self._prevButton.setEnabled(False)

        self._pagesLabel = QLabel('of 10 for ', self)
        self._itemsLabel = QLabel(' items per page', self)

        # define the interface
        layout = QHBoxLayout()
        layout.addWidget(QLabel('Page', self))
        layout.addWidget(self._prevButton)
        layout.addWidget(self._pagesSpinner)
        layout.addWidget(self._nextButton)
        layout.addWidget(self._pagesLabel)
        layout.addWidget(self._pageSizeCombo)
        layout.addWidget(self._itemsLabel)
        layout.addStretch(1)

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

        self.setLayout(layout)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)

        # create connections
        self._pageSizeCombo.currentIndexChanged.connect(self.pageSizePicked)
        self._nextButton.clicked.connect(self.gotoNext)
        self._prevButton.clicked.connect(self.gotoPrevious)
        self._pagesSpinner.editingFinished.connect(self.assignCurrentPage)

    def assignCurrentPage(self):
        """
        Assigns the page for the spinner to be current.
        """
        self.setCurrentPage(self._pagesSpinner.value())

    def currentPage(self):
        """
        Reutrns the current page for this widget.
        
        :return     <int>
        """
        return self._currentPage

    @Slot()
    def gotoFirst(self):
        """
        Goes to the first page.
        
        :sa     setCurrentPage
        """
        self.setCurrentPage(1)

    @Slot()
    def gotoLast(self):
        """
        Goes to the last page.
        
        :sa     setCurrentPage
        """
        self.setCurrentPage(self.pageCount())

    @Slot()
    def gotoNext(self):
        """
        Goes to the next page.
        
        :sa     setCurrentPage
        """
        next_page = self.currentPage() + 1
        if (next_page > self.pageCount()):
            return

        self.setCurrentPage(next_page)

    @Slot()
    def gotoPrevious(self):
        """
        Goes to the previous page.
        
        :sa     setCurrentPage
        """
        prev_page = self.currentPage() - 1
        if (prev_page == 0):
            return

        self.setCurrentPage(prev_page)

    def itemCount(self):
        """
        Returns the total number of items this widget holds.  If no item count
        is defined, it will not be displayed in the label, otherwise it will
        show.
        
        :return     <int>
        """
        return self._itemCount

    def itemsTitle(self):
        """
        Returns the items title for this instance.
        
        :return     <str>
        """
        return self._itemsTitle

    def pageCount(self):
        """
        Returns the number of pages that this widget holds.
        
        :return     <int>
        """
        return self._pageCount

    def pageSize(self):
        """
        Returns the number of items that should be visible in a page.
        
        :return     <int>
        """
        return self._pageSize

    def pageSizeOptions(self):
        """
        Returns the list of options that will be displayed for this default
        size options.
        
        :return     [<str>, ..]
        """
        return map(str, self._pageSizeCombo.items())

    def pageSizePicked(self, pageSize):
        """
        Updates when the user picks a page size.
        
        :param      pageSize | <str>
        """
        try:
            pageSize = int(self._pageSizeCombo.currentText())
        except ValueError:
            pageSize = 0

        self.setPageSize(pageSize)
        self.pageSizeChanged.emit(pageSize)

    def refreshLabels(self):
        """
        Refreshes the labels to display the proper title and count information.
        """
        itemCount = self.itemCount()
        title = self.itemsTitle()

        if (not itemCount):
            self._itemsLabel.setText(' %s per page' % title)
        else:
            msg = ' %s per page, %i %s total' % (title, itemCount, title)
            self._itemsLabel.setText(msg)

    @Slot(int)
    def setCurrentPage(self, pageno):
        """
        Sets the current page for this widget to the inputed page.
        
        :param      pageno | <int>
        """
        if (pageno == self._currentPage):
            return

        if (pageno <= 0):
            pageno = 1

        self._currentPage = pageno

        self._prevButton.setEnabled(pageno > 1)
        self._nextButton.setEnabled(pageno < self.pageCount())

        self._pagesSpinner.blockSignals(True)
        self._pagesSpinner.setValue(pageno)
        self._pagesSpinner.blockSignals(False)

        if (not self.signalsBlocked()):
            self.currentPageChanged.emit(pageno)

    @Slot(int)
    def setItemCount(self, itemCount):
        """
        Sets the item count for this page to the inputed value.
        
        :param      itemCount | <int>
        """
        self._itemCount = itemCount
        self.refreshLabels()

    @Slot(str)
    def setItemsTitle(self, title):
        """
        Sets the title that will be displayed when the items labels are rendered
        
        :param      title | <str>
        """
        self._itemsTitle = str(title)
        self.refreshLabels()

    @Slot(int)
    def setPageCount(self, pageCount):
        """
        Sets the number of pages that this widget holds.
        
        :param      pageCount | <int>
        """
        if (pageCount == self._pageCount):
            return

        pageCount = max(1, pageCount)

        self._pageCount = pageCount
        self._pagesSpinner.setMaximum(pageCount)
        self._pagesLabel.setText('of %i for ' % pageCount)

        if (pageCount and self.currentPage() <= 0):
            self.setCurrentPage(1)

        elif (pageCount < self.currentPage()):
            self.setCurrentPage(pageCount)

        if (not self.signalsBlocked()):
            self.pageCountChanged.emit(pageCount)

        self._prevButton.setEnabled(self.currentPage() > 1)
        self._nextButton.setEnabled(self.currentPage() < pageCount)

    @Slot(int)
    def setPageSize(self, pageSize):
        """
        Sets the number of items that should be visible in a page.  Setting the
        value to 0 will use all sizes
        
        :return     <int>
        """
        if self._pageSize == pageSize:
            return

        self._pageSize = pageSize

        # update the display size
        ssize = str(pageSize)
        if (ssize == '0'):
            ssize = ''

        self._pageSizeCombo.blockSignals(True)
        index = self._pageSizeCombo.findText(ssize)
        self._pageSizeCombo.setCurrentIndex(index)
        self._pageSizeCombo.blockSignals(False)

    def setPageSizeOptions(self, options):
        """
        Sets the options that will be displayed for this default size.
        
        :param      options | [<str>,. ..]
        """
        self._pageSizeCombo.blockSignals(True)
        self._pageSizeCombo.addItems(options)

        ssize = str(self.pageSize())
        if (ssize == '0'):
            ssize = ''

        index = self._pageSizeCombo.findText()
        self._pageSizeCombo.setCurrentIndex(index)
        self._pageSizeCombo.blockSignals(False)

    x_itemsTitle = Property(str, itemsTitle, setItemsTitle)
    x_pageCount = Property(int, pageCount, setPageCount)
    x_pageSize = Property(int, pageSize, setPageSize)
    x_pageSizeOptions = Property(list, pageSizeOptions, setPageSizeOptions)
Example #5
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)