【问题标题】:Python/PyQT: How can I truncate a text in QLineEditPython/PyQT:如何在 QLineEdit 中截断文本
【发布时间】:2016-07-17 15:23:30
【问题描述】:

我正在为我的问题寻找解决方案。我做了什么?我编写了一个继承自 QLineEdit 的名为 ExtendedTruncateTextLineEdit 的子类。我想要的是?好吧,当您调整窗口大小并且 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()

【问题讨论】:

  • 什么是ExtendedTruncateTextLabel

标签: python qt4 pyqt4


【解决方案1】:

这是您可能想要的粗略版本。我在大约 10 分钟内把它煮熟了,所以非常粗糙。请注意,这绝不会接近完成。它还有几件事要做。在这种情况下,当QLineEdit 失去焦点时,文本将被忽略。文本获得焦点后必须恢复。该部分尚未实施。否则字体的更改将导致错误的省略,因为QFontMentrics 对象不会被更改,等等……

class ElidingLineEdit( QLineEdit ) :
    """Eliding text lineedit
    """

    def __init__( self, text = QString(), parent = None ) :
        """Class initialiser
        """

        QLineEdit.__init__( self, parent )
        self.mText = text;

        self.fm = QFontMetrics( self.font() )

        self.textEdited[ QString ].connect( self.saveText )
        self.editingFinished.connect( self.shortenText )

    def setText( self, txt ) :
        """setText( QString ) -> None

        Override the QLineEdit::setText to display the shortened text

        @return None
        """

        QLineEdit.setText( self, self.fm.elidedText( self.mText, Qt.ElideRight, self.width() ) )

    def resizeEvent( self, rEvent ) :
        """resizeEvent( QResizeEvent ) -> None

        Override the resizeevent to shorten the text

        @return None
        """

        QLineEdit.setText( self, self.fm.elidedText( self.mText, Qt.ElideRight, rEvent.size().width() ) )

        rEvent.accept()

    def saveText( self, newText ) :
        """saveText() -> None

        Save the text as it is changing

        @return None
        """

        self.mText = newText

    def shortenText( self ) :
        """saveText() -> None

        Save the text as it is changing

        @return None
        """

        QLineEdit.setText( self, self.fm.elidedText( self.mText, Qt.ElideRight, self.width() ) )

【讨论】:

    【解决方案2】:

    我在一个项目中也需要这个,所以我把 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()))
    

    【讨论】:

    • 我想我找到了解决方案。看看我的回答。
    【解决方案3】:

    对于 Spencer 和其他用户,我想我有一个解决方案。以下方案适用于以下可执行程序。当用户运行这个程序并且他正在输入一个很长的文本时,程序不会缩短文本。如果该小部件保持焦点 (FocusIn),QLineEdit() 中的长文本也不会被截断,但用户会调整窗口大小。这意味着,只要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_())
    

    【讨论】:

      猜你喜欢
      • 2012-07-11
      • 1970-01-01
      • 2020-06-12
      • 2014-04-19
      • 2018-08-11
      • 2012-08-24
      • 2018-02-15
      • 2017-11-23
      相关资源
      最近更新 更多