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
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())
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
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)
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)