Getting visible text from a QTextEdit in PyQt

ely picture ely · Jun 24, 2011 · Viewed 11.3k times · Source

This is related to another question I found here that seems to be inactive for a few months, so I think it's worth asking again.

I have created a simple QDialog that has a QTextEdit and a QPushButton. This pops up in my application when a user right-clicks and selects the option to "add comments". I want them to be able to write free-form text and I'll just save whatever they write as a long string with no concern for new lines, etc.

When the user clicks the button, it executes code like this:

    self.connect(accept_button,QtCore.SIGNAL('clicked()'),lambda arg=str(view_textedit.toPlainText()): self.updateGroupComments(arg))

def updateGroupComments(self,new_comment_str):
    print "Updating user comment to have new string: " + new_comment_str
    self.group_entry.list_of_user_comments[self.currentFrameCounter] = new_comment_str

This is not detecting the TextEdit text that is visible (it only detects whatever the text edit text is set to when it is created). How do I make a simple command that returns the currently visible text from a QTextEdit. Again, the function

toPlainText()

is not working correctly... it doesn't find the currently visible text, only whatever text was on screen before changes or additions started being made by the user.

If this can't be done without subclassing and appealing to cursor positions, it makes the whole thing seem worthless... so please keep suggestions only to those implemented without subclassing or manipulating cursors. It should be really simple and straightforward to just return all currently visible text... what am I missing?

Answer

Cat Plus Plus picture Cat Plus Plus · Jun 24, 2011

Objects that are being bound to default arguments are evaluated at the definition time. The function is working correctly, it returns whatever was in the text field when it was executed. Your code simply calls it at the wrong moment. If you want to use lambda, then do:

self.connect(
    accept_button, QtCore.SIGNAL('clicked()'),
    lambda: self.updateGroupComments(str(view_textedit.toPlainText()))
)

Or make view_textedit an instance attribute instead, and do simply

self.connect(
    accept_button, QtCore.SIGNAL('clicked()'), self.updateGroupComments
)

And change updateGroupComments to call self.view_textedit.toPlainText instead of taking an argument.

BTW, this is not PyQt specific, this is how Python works in general.

To illustrate my last comment, that lambda can very well be replaced with:

def slot():
    self.updateGroupComments(str(view_textedit.toPlainText()))

self.connect(accept_button, QtCore.SIGNAL('clicked()'), slot)