class EditableLabel(QLabel): def __init__(self, save, failCallback, *args, **kwargs): QLabel.__init__(self, *args, **kwargs) self.save = save self.editable = True self.failCallback = failCallback self.editor = QLineEdit(self) self.editor.setWindowFlags(Qt.Popup) self.editor.setFocusProxy(self) self.editor.editingFinished.connect(self.handleEditingFinished) self.editor.installEventFilter(self) self.callback = lambda text: 0 def eventFilter(self, widget, event): if ((event.type() == QEvent.MouseButtonPress and not self.editor.geometry().contains(event.globalPos())) or (event.type() == QEvent.KeyPress and event.key() == Qt.Key_Escape)): self.editor.hide() return True return QLabel.eventFilter(self, widget, event) def disableEdit(self): self.editable = False self.editor.hide() def enableEdit(self): self.editable = True def mouseDoubleClickEvent(self, event=None): if not self.editable: if self.failCallback: self.failCallback() return rect = self.rect() self.editor.setFixedSize(rect.size()) self.editor.move(self.mapToGlobal(rect.topLeft())) self.editor.setText(self.text()) self.editor.setFocus(Qt.MouseFocusReason) self.editor.selectAll() if not self.editor.isVisible(): self.editor.show() def handleEditingFinished(self): text = self.editor.text() self.editor.hide() if self.save: self.setText(text) self.callback(text)
class AbstractReferenceSelector(QWidget): changed = Signal() def __init__(self, parent=None): QWidget.__init__(self, parent) self.completer = None self.p_selected_id = 0 self.layout = QHBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.name = QLineEdit() self.name.setText("") self.layout.addWidget(self.name) self.details = QLabel() self.details.setText("") self.details.setVisible(False) self.layout.addWidget(self.details) self.button = QPushButton("...") self.button.setFixedWidth( self.button.fontMetrics().horizontalAdvance("XXXX")) self.layout.addWidget(self.button) self.setLayout(self.layout) self.setFocusProxy(self.name) self.button.clicked.connect(self.on_button_clicked) if self.details_field: self.name.setFixedWidth( self.name.fontMetrics().horizontalAdvance("X") * 15) self.details.setVisible(True) self.completer = QCompleter(self.dialog.model.completion_model) self.completer.setCompletionColumn( self.dialog.model.completion_model.fieldIndex(self.selector_field)) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.name.setCompleter(self.completer) self.completer.activated[QModelIndex].connect(self.on_completion) def getId(self): return self.p_selected_id def setId(self, selected_id): if self.p_selected_id == selected_id: return self.p_selected_id = selected_id self.name.setText( self.dialog.model.getFieldValue(selected_id, self.selector_field)) if self.details_field: self.details.setText( self.dialog.model.getFieldValue(selected_id, self.details_field)) selected_id = Property(int, getId, setId, notify=changed, user=True) def setFilterValue(self, filter_value): self.dialog.setFilterValue(filter_value) def on_button_clicked(self): ref_point = self.mapToGlobal(self.name.geometry().bottomLeft()) self.dialog.setGeometry(ref_point.x(), ref_point.y(), self.dialog.width(), self.dialog.height()) res = self.dialog.exec(enable_selection=True, selected=self.selected_id) if res: self.selected_id = self.dialog.selected_id self.changed.emit() @Slot(QModelIndex) def on_completion(self, index): model = index.model() self.selected_id = model.data(model.index(index.row(), 0), Qt.DisplayRole) self.changed.emit() def isCustom(self): return True