class ClearableLineEdit(QLineEdit): HEIGHT = 32 def __init__(self, filter_updater, parent=None): """ :type filter_updater: (str) -> None :type parent: QWidget """ super().__init__(parent) self._filter_updater = lambda: filter_updater(self.text()) self.setFixedHeight(self.HEIGHT) self.setMaxLength(48) self.setMaximumWidth(200) self._tool_button = QToolButton(self) self._tool_button.setIcon(QIcon(resource_filepath("clear.png"))) self._tool_button.setStyleSheet("QToolButton {" " border: none;" " padding: 0px;" "}") frame_width = self._getFrameWidth() icon_side = self.HEIGHT - 2 * frame_width self._tool_button.setFixedSize(icon_side, icon_side) self._tool_button.clicked.connect(self.onClearButton) self._tool_button.hide() self.textChanged.connect(self.updateFilter) stylesheet = \ "QLineEdit {{" \ " padding-right: {}px;" \ " background-color: #FFFFFF;" \ "}}".format(self._tool_button.sizeHint().width() + frame_width + 1) self.setStyleSheet(stylesheet) def resizeEvent(self, event): super().resizeEvent(event) self._updateSize() def _updateSize(self): size = self._tool_button.size() """:type: QSize""" frame_width = self._getFrameWidth() rect = self.rect() """:type: QRect""" x = rect.right() - frame_width - size.width() y = (rect.bottom() + 1 - size.height()) / 2 self._tool_button.move(x, y) def _getFrameWidth(self): return self.style().pixelMetric(QStyle.PM_DefaultFrameWidth) def onClearButton(self): self.clear() def updateFilter(self): self._tool_button.setVisible(len(self.text()) > 0) self._filter_updater()
class SearchEdit(QLineEdit): ''' SearchEdit Styled search edit box which includes a search icon, clear button, and pre-defined preview text. ''' def __init__(self, parent=None): super(SearchEdit, self).__init__(parent) clr_pixmap = QPixmap(':/icons/clear.png') self._btn_clear = QToolButton(self) self._btn_clear.setIcon(clr_pixmap) self._btn_clear.setIconSize(clr_pixmap.size()) self._btn_clear.setCursor(Qt.ArrowCursor) self._btn_clear.setStyleSheet('QToolButton { border: none; padding: 0px; }'); self._btn_clear.clicked.connect(self.clear) fw = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth) #TODO: Make a Search glyph show up properly self.setStyleSheet('QLineEdit { padding-right: %dpx; }' % (self._btn_clear.sizeHint().width() + fw + 1)) msz = self.minimumSizeHint() self.setMinimumSize(max([msz.width(), self._btn_clear.sizeHint().height() + fw * 2 + 2]), max([msz.height(), self._btn_clear.sizeHint().height() + fw * 2 + 2])) self.setPlaceholderText('Search') def resizeEvent(self, e): sz = self._btn_clear.sizeHint() fw = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth) self._btn_clear.move(self.rect().right() - fw - sz.width(), (self.rect().bottom() + 1 - sz.height()) / 2 + 1) def sizeHint(self): s = super(SearchEdit, self).sizeHint() s.setWidth(250) return s
class LabelFilterEdit(QLineEdit): clear_button = None def __init__(self, parent=None): QLineEdit.__init__(self, parent) self.clear_button = QToolButton(self) self.clear_button.setText("clear") self.clear_button.hide() self.clear_button.clicked.connect(self.clear) # self.clear_button.setIcon(QIcon(":/denied.png")) self.textChanged.connect(self.update_clear_button) def resizeEvent(self, *args, **kwargs): super(LabelFilterEdit, self).resizeEvent(*args, **kwargs) sz = self.clear_button.sizeHint() frameWidth = 0 #self.style().pixelMetric(QStyle.PM_DefaultFrameWidth) self.clear_button.move(self.rect().right() - sz.width() - frameWidth, (self.rect().bottom() + 1 - sz.height()) / 2) def update_clear_button(self, text): self.clear_button.setVisible(len(text)>0)