Hallo Leute,
ich möchte dieses Thema wiederbeleben. Ein neues Thema mit dem gleichen Inhalt zu eröffnen, erschien mir unangemessen. Im nachfolgenden Quelltext seht ihr ein ausführbares Programm. Es geht um das Verkürzen eines Textes im
QLineEdit(). Im Gegensatz zu meiner früheren Vorstellung geht es hierbei darum, dass der Benutzer innerhalb der
QLineEdit() interagieren kann. Das Programm funktioniert soweit tadellos.
Was funktioniert schon mal?
Wenn der Benutzer das Programm startet und im
QLineEdit() einen sehr laaaaaaaaangen Text eintippt, dann wird der Text noch nicht verkürzt angezeigt. Sobald aber das
QLineEdit() den Fokus verliert, wird der Text verkürzt angezeigt. Um den Fokus zu verlieren habe ich absichtlich ein
QPushButton() eingebaut. Wenn der Benutzer das Fenster größer zieht, wird der originale Text angezeigt, soweit das
QLineEdit() es zulässt.
Was funktioniert NICHT?
Angenommen, der Benutzer möchte später noch einmal den laaaaangen Text ändern und klickt in dieses Widget. Meine Idee ist, dass im Widget dann der originale Text angezeigt wird - eben ungekürzt. Dies habe ich auch in der
setText()-Methode von der
ElidingLineEdit()-Klasse auch versucht - daher auch das Argument
'allow_truncate_text '. Aber irgendwie will mir das nicht gelingen.
Code: Alles auswählen
import sys
from PyQt4.QtCore import Qt, QEvent, QString
from PyQt4.QtGui import (QApplication, QLineEdit, QFontMetrics, QVBoxLayout,
QWidget, QPushButton)
class ElidingLineEdit(QLineEdit):
def __init__(self, text = QString(), parent = None):
'''
NOTICE:
=======
Class initialiser for Eliding text lineedit
'''
QLineEdit.__init__(self, parent)
self.saved_text = text
self.font_metrics = QFontMetrics(self.font())
self.textEdited[QString].connect(self.saveText)
self.editingFinished.connect(self.shortenText)
def setText(self, text, allow_truncate_text = True):
'''
NOTICE:
=======
Override the setText()-method of QLineEdit()-class to display
the shortened text.
PARAMETERS:
===========
:text - The given text that holds the current widget's text.
:allow_truncate_text - Defines whether the given text should be shortened.
By default the given text should be shortend.
:return - Nothing is returned. The statement 'return'
terminates a function. That makes sure that the
function is definitely finished.
'''
# For example the QLineEdit loses the focus (FocusOut), the text has to be shortened.
if allow_truncate_text:
QLineEdit.setText(self, self.font_metrics.elidedText(self.saved_text, Qt.ElideRight, self.width() -10))
else:
# Otherwise the QLineEdit gets the focus, the text should NOT be shortened.
# For example: The user is typing a text or later he clicks this QLineEdit()
# again to change the text possibly
print "Original text", unicode(self.saved_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.
'''
QLineEdit.setText(self, self.font_metrics.elidedText(self.saved_text, Qt.ElideRight, rEvent.size().width() -10))
rEvent.accept()
return
def saveText(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 shortenText(self ):
'''
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.
'''
QLineEdit.setText( self, self.font_metrics.elidedText( self.saved_text, Qt.ElideRight, self.width() ) )
return
class Example(QWidget):
def __init__(self):
QWidget.__init__(self)
self.setMinimumWidth(80)
self.init_ui()
# This attribute is used to say
# whether a text should be displayed original or not.
# By default, the text shouldn't be displayed original.
self._show_original_text = False
self._original_text = ""
self._copied_original_text = None
def init_ui(self):
# Create an instance of QLineEdit()
self.line_edit_text = ElidingLineEdit()
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.textChanged.connect(lambda text: self.handle_text_change(text, allow_cut_text = False))
def handle_text_change(self,
text = None,
allow_cut_text = True):
self._original_text = text
self.line_edit_text.setText(text, allow_truncate_text = allow_cut_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._show_original_text = False
self.line_edit_text.setText(self.line_edit_text.saved_text, allow_truncate_text = False)
if event.type() == QEvent.FocusOut:
if obj == self.line_edit_text:
self._show_original_text = True
self.line_edit_text.setText(self._original_text, allow_truncate_text = True)
return super(QWidget, self).eventFilter(obj, event)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Example()
window.show()
sys.exit(app.exec_())