File: prompt_line_edit.py

package info (click to toggle)
turing 0.11-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,340 kB
  • sloc: python: 106,582; xml: 101; makefile: 53; sh: 29
file content (115 lines) | stat: -rw-r--r-- 4,093 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""
This module contains the PromptLineEdit widget implementation.

"""
import os
from pyqode.core import icons
from pyqode.qt import QtWidgets, QtCore, QtGui
from pyqode.qt import PYQT5_API
from pyqode.qt import PYQT4_API
from pyqode.qt import PYSIDE_API


class PromptLineEdit(QtWidgets.QLineEdit):

    """
    Extends QLineEdit to show a prompt text and a clear icon
    """

    #: Signal emitted when the embedded button is clicked
    clear_clicked = QtCore.Signal()

    def __init__(self, parent=None,
                 prompt_text=_(' Search'), button_icon=None):
        super(PromptLineEdit, self).__init__(parent)
        self._margin = self.sizeHint().height() - 2
        self._spacing = 0
        self._prompt_text = prompt_text

        self.button = QtWidgets.QToolButton(self)
        if button_icon is None:
            button_icon = icons.icon(
                'edit-clear', ':/pyqode-icons/rc/clear-left.png',
                'fa.times-circle')
        self.button.setIcon(button_icon)
        self.button.setToolTip(_("Clear"))
        self.button.setStyleSheet(
            "QToolButton { border: none; padding: 5px; }")
        self.button.setCursor(QtCore.Qt.ArrowCursor)
        self.button.setFocusPolicy(QtCore.Qt.NoFocus)
        self.set_button_visible(False)
        self.textChanged.connect(self._on_text_changed)
        self.button.clicked.connect(self.clear)
        self.button.clicked.connect(self.clear_clicked.emit)

    @property
    def prompt_text(self):
        """
        Gets/Sets the prompt text.
        """
        return self._prompt_text

    @prompt_text.setter
    def prompt_text(self, prompt):
        self._prompt_text = prompt
        self.update()

    def paintEvent(self, event):
        super(PromptLineEdit, self).paintEvent(event)

        qt_api = os.environ['QT_API'].lower()
        if self._prompt_text and not self.text() and self.isEnabled():
            if qt_api in PYQT4_API:
                from PyQt4.QtGui import QStyleOptionFrameV3
                option = QStyleOptionFrameV3()
            elif qt_api in PYSIDE_API:
                from PySide.QtGui import QStyleOptionFrameV3
                option = QStyleOptionFrameV3()
            elif qt_api in PYQT5_API:
                from PyQt5.QtWidgets import QStyleOptionFrame
                option = QStyleOptionFrame()
            else:
                msg = 'Qt bindings "%s" is not supported' % qt_api
                raise PythonQtError(msg)

            self.initStyleOption(option)

            left, top, right, bottom = self.getTextMargins()

            va = self.style().visualAlignment(
                self.layoutDirection(), self.alignment())
            rect = self.style().subElementRect(
                QtWidgets.QStyle.SE_LineEditContents, option, self).adjusted(
                    2, 0, 0, 0).adjusted(left, top, -right, -bottom)
            fm = QtGui.QFontMetrics(self.font())
            text = fm.elidedText(
                self._prompt_text, QtCore.Qt.ElideRight, rect.width())
            painter = QtGui.QPainter(self)
            painter.setPen(self.palette().color(
                QtGui.QPalette.Disabled, QtGui.QPalette.Text))
            painter.drawText(rect, va, text)

    def resizeEvent(self, event):
        # Adjusts Clear button position
        super(PromptLineEdit, self).resizeEvent(event)
        self.button.resize(QtCore.QSize(self._margin, self.height() - 2))
        self.button.move(self.width() - self._margin - 3, 0)

    def set_button_visible(self, visible):
        """
        Sets the clear button as ``visible``

        :param visible: Visible state (True = visible, False = hidden).
        """
        self.button.setVisible(visible)
        left, top, right, bottom = self.getTextMargins()
        if visible:
            right = self._margin + self._spacing
        else:
            right = 0
        self.setTextMargins(left, top, right, bottom)

    def _on_text_changed(self, text):
        """Text changed, update Clear button visibility
        """
        self.set_button_visible(len(text) > 0)