class DistanceWidget(QWidget): """ Widget used to manually edit the selection radius""" distanceChanged = pyqtSignal(float) distanceEditingFinished = pyqtSignal(Qt.KeyboardModifiers) distanceEditingCanceled = pyqtSignal() def __init__(self, label, parent=None): super().__init__(parent) layout = QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setAlignment(Qt.AlignLeft) if label: self.label = QLabel(label, self) self.label.setAlignment(Qt.AlignRight | Qt.AlignCenter) layout.addWidget(self.label) self.spinbox = QgsDoubleSpinBox(self) self.spinbox.setSingleStep(1) self.spinbox.setValue(0) self.spinbox.setMinimum(0) self.spinbox.setMaximum(1000000000) self.spinbox.setDecimals(6) self.spinbox.setShowClearButton(False) self.spinbox.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred) layout.addWidget(self.spinbox) # connect signals self.spinbox.installEventFilter(self) self.spinbox.valueChanged.connect(self.distanceChanged.emit) # config focus self.setFocusProxy(self.spinbox) def set_distance(self, distance): """ set the selection radius """ self.spinbox.setValue(distance) self.spinbox.selectAll() def distance(self): """ return he selection radius """ return self.spinbox.value() def eventFilter(self, obj, event): """ Intercept key press event to emit our own custom signals """ # pylint: disable=invalid-name if obj is self.spinbox and event.type() == QEvent.KeyPress: if event.key() == Qt.Key_Escape: self.distanceEditingCanceled.emit() return True if event.key() in (Qt.Key_Enter, Qt.Key_Return): # Emit the editing finished signal with modifier to handle remove # from selection and add to selection self.distanceEditingFinished.emit(event.modifiers()) return True return False