Python / PyQT:如何截断QLineEdit中的文本

时间:2016-03-29 21:02:10

标签: python qt4 pyqt4

我正在为我的问题寻找解决方案。我做了什么?我写了一个名为 ExtendedTruncateTextLineEdit 的子类,它继承自QLineEdit。我想要的是?好吧,当你调整窗口大小并且QLineEdit变得比内容小时,我想在名为 QLineEdit 的Qwidget中截断文本。以下代码确实有效,但QLineEdit-widget看起来像QLabel。我需要做的是,以下代码还绘制了我的QLineEdit?

import sys
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QApplication,\
                        QLineEdit,\
                        QLabel,\
                        QFontMetrics,\
                        QHBoxLayout,\
                        QVBoxLayout,\
                        QWidget,\
                        QIcon,\
                        QPushButton,\
                        QToolTip,\
                        QBrush,\
                        QColor,\
                        QFont,\
                        QPalette,\
                        QPainter

qt_app = QApplication(sys.argv)

class Example(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setMinimumWidth(100)

        self.init_ui()


    def init_ui(self):
        v_layout = QVBoxLayout()
        v_layout.addStretch(1)

        lbl = ExtendedTruncateTextLabel("This is a really, long and poorly formatted runon sentence used to illustrate a point", self)
        #lbl.setText("This is a really, long and poorly formatted runon sentence used to illustrate a point")

        lbl_1 = ExtendedTruncateTextLabel(self)
        lbl_1.setText("Dies ist ein normaler Text")

        l_text = ExtendedTruncateTextLineEdit()
        l_text.setText("In the widget namend QLineEdit is also a very long text")


        v_layout.addWidget(lbl)
        v_layout.addWidget(lbl_1)
        v_layout.addWidget(l_text)

        self.setLayout(v_layout)

    def run(self):
        self.show()
        qt_app.exec_()

class ExtendedTruncateTextLineEdit(QLineEdit):   
    def __init(self, parent):
        QLineEdit.__init__(self, parent)

    def paintEvent(self, event):

        """ Handle the paint event for the title bar.

        This paint handler draws the title bar text and title buttons.

        """
        super(ExtendedTruncateTextLineEdit, self).paintEvent(event)
        painter = QPainter(self)

        metrics = QFontMetrics(self.font())
        elided  = metrics.elidedText(self.text(), Qt.ElideMiddle, self.width())

        painter.drawText(self.rect(), self.alignment(), elided)

if __name__ == '__main__':
    app = Example()
    app.run()

3 个答案:

答案 0 :(得分:3)

这是您可能想要的粗略版本。我在大约10分钟内煮熟了,所以非常粗糙。请注意,这在没有任何地方接近完成。它还有几件事要做。在这种情况下,当 Toolbar toolbar = (Toolbar) findViewById(R.id.editProfileToolbar); this.setSupportActionBar(toolbar); 失去焦点时,文本将被省略。当文本获得焦点时,必须恢复该文本。该部分尚未实施。或更改字体将导致错误的删除,因为QLineEdit对象不会被更改,等等...

QFontMentrics

答案 1 :(得分:0)

我也需要这个项目,所以我进一步考虑了Marcus的答案,并进行了focusIn和focusOut处理。

由于某种原因,当我致电self.end()self.setCursorPosition(len(self.text())似乎没有做太多事情......如果有人可以改进,那就让我知道了。

class ElidingQLineEdit(QtGui.QLineEdit):
    def __init__(self, text= ""):
        super(ElidingQLineEdit, self).__init__()
        self.mText = text
        self.fm = QtGui.QFontMetrics(self.font())

        self.textEdited.connect(self.saveText)
        self.editingFinished.connect(self.elideText)


    def setText(self, text, elide=True):
        self.mText = text
        if elide:
            QtGui.QLineEdit.setText(self, self.fm.elidedText(text, QtCore.Qt.ElideMiddle, self.width()))
        else:
            QtGui.QLineEdit.setText(self, text)


    def resizeEvent(self, rEvent):
        QtGui.QLineEdit.setText(self, self.fm.elidedText(self.mText, QtCore.Qt.ElideMiddle, rEvent.size().width()))
        rEvent.accept()


    def saveText(self, newText):
        self.mText = newText


    def focusInEvent(self, QFocusEvent):
        super(ElidingQLineEdit, self).focusInEvent(QFocusEvent)
        self.setText(self.mText, False)
        self.setCursorPosition(len(self.text()))


    def focusOutEvent(self, QFocusEvent):
        super(ElidingQLineEdit, self).focusOutEvent(QFocusEvent)
        self.setText(self.mText, True)


    def elideText(self):
        QtGui.QLineEdit.setText(self, self.fm.elidedText(self.mText, QtCore.Qt.ElideMiddle, self.width()))

答案 2 :(得分:0)

对于Spencer和其他用户,我认为我有一个解决方案。以下方案适用于以下可执行程序。当用户运行该程序并且他正在键入loooong文本时,程序不会缩短文本。如果该窗口小部件保留焦点(QLineEdit()),则FocusIn中的长文本也不会被截断,但用户会调整窗口大小。这意味着,只要QLineEdit()保持焦点(FocusIn),文本就不会缩短。只有当QLineEdit()失去焦点(FocusOut)时,文本才会缩短。之后,当用户决定编辑非常低调的文本并点击QLineEdit()时,文本会显示而不会出现任何短路。

class Example(QWidget):
    def __init__(self, elide = Qt.ElideMiddle, parent = None):
        QWidget.__init__(self, parent)

        self.setMinimumWidth(80)

        self.font_metrics = QFontMetrics(self.font())

        self.saved_text = ""

        self._elide = elide

        self._show_original_text = False

        self.init_ui()

    def init_ui(self):
        #   Create an instance of QLineEdit()
        self.line_edit_text = QLineEdit()
        self.line_edit_text.setPlaceholderText("Hell world I am here where you are")
        #   We must implement the eventFilter method
        #   and enable this property to the widgets that are needed with
        self.line_edit_text.installEventFilter(self)

        #   Create an instance of QPushButton()
        self.push_button = QPushButton("Just click me, nothing will happen.")
        self.push_button.installEventFilter(self)

        #   Add the both widgets to the layout, that is created.
        v_layout = QVBoxLayout()
        v_layout.addStretch(1)
        v_layout.addWidget(self.line_edit_text)
        v_layout.addWidget(self.push_button)
        self.setLayout(v_layout)

        #   Set a slot, connect() the textChanged-slot to the handle_text_change()-method.
        self.line_edit_text.textEdited[QString].connect(self.save_text)

    def eventFilter(self, obj, event):
        #   The eventFilter method has as information
        #   the object and type of event. So we have to
        #   listen to the focus events.
        if event.type() == QEvent.FocusIn:
            if obj == self.line_edit_text:
                self.line_edit_text.setText(self.saved_text)
                print "You clicked in the LineEdit"
                self._show_original_text = True
        if event.type() == QEvent.FocusOut:
            if obj == self.line_edit_text:
                print "You lost focus"
                self._show_original_text = False
                self.line_edit_text.setText(self.font_metrics.elidedText(self.saved_text, self._elide, self.width() -35))
        return super(QWidget, self).eventFilter(obj, event)

    def save_text(self, new_text):
        '''
            NOTICE:
            =======
            Implement the saveText()-method to save the text as it is changing.

            PARAMETERS:
            ===========
            :new_text   -   The given text have to save.

            :return     -   Nothing is returned. The statement 'return'
                            terminates a function. That makes sure that the
                            function is definitely finished.
        '''
        self.saved_text = new_text

        return

    def resizeEvent(self, rEvent):
        '''
            NOTICE:
            =======
            Override the resizeevent()-method of QLineEdit()-class to shorten the text.

            PARAMETERS:
            ===========
            :rEvent     -   The given QResizeEvent class contains event
                            parameters for resize events - for example accept()-method.

            :return     -   Nothing is returned. The statement 'return'
                            terminates a function. That makes sure that the
                            function is definitely finished.
        '''
        if not self._show_original_text:
            self.line_edit_text.setText(self.font_metrics.elidedText(self.saved_text, self._elide, rEvent.size().width() -35))

        rEvent.accept()

        return


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Example()
    window.show()
    sys.exit(app.exec_())