-1

I want to do some search and replace in a QTextEdit but QTextEdit.find() always returns False/finds nothing. Where is my mistake?

Here is a (very) minimal reproducible example:

from PySide2.QtWidgets import QApplication, QTextEdit
from PySide2.QtGui import QTextCursor
import sys

app = QApplication(sys.argv)
textedit = QTextEdit()
cursor = textedit.textCursor()
cursor.insertText("test test test")
cursor.movePosition(QTextCursor.Start)
print(textedit.find("t"))
textedit.show()
app.exec_()

Thx for that -.-: "This question already has an answer here: QTextEdit.find() doesn't work in Python"

That is not true. (Maybe read the questions and answers before stating something like that and closing questions. This is the behavior why stackoverflow has such a bad reputation.): "The problem is the position of the cursor in the window. By default the search only happens forward (= from the position of the cursor onwards). But i set my cursor to the start of the document via cursor.movePosition(QTextCursor.Start)

Koyagi
  • 143
  • 6
  • does this help https://stackoverflow.com/a/6593475/12502959 – python_user Dec 10 '20 at 14:38
  • 2
    code works for me when I use `textedit.moveCursor()` instead of `cursor.moveCursor()` – furas Dec 10 '20 at 14:47
  • python_learner and eyllanesc: Nope. @furas thx, that works. Still awkward it does not work with "cursor.movePosition" – Koyagi Dec 10 '20 at 14:52
  • I found that `textedit.textCursor()` creates local copy and it doesn't change original position - and at the end you have to use `textedit.setTextCursor(cursor)` – furas Dec 10 '20 at 15:03
  • see `textedit.setTextCursor(cursor)` in answer [Moving the cursor in a PyQt5 text edit doesn't work](https://stackoverflow.com/a/43305350/1832058) – furas Dec 10 '20 at 15:09
  • @Koyagi 1. moving the position of the textCursor is not enough, it must be set back in the textEdit. It's not "strange", there can be many concurrent QTextCursor objects and the "actual" cursor position can only be set when the text cursor is set back on the widget. 2. If you don't agree with the duplicate there's nothing wrong: there are thousands questions reviewed each day, it's completely normal for reviewers to make mistakes, so just clarify your reasons without useless remarks (your complains are completely off topic and unnecessary to other people reading your question). – musicamante Dec 10 '20 at 15:22
  • To me it is strange that find() requires the "actual" cursor and not just one of those concurrent QTextCursor objects (while most other operations do not). – Koyagi Dec 10 '20 at 15:36
  • @Koyagi it's not that strange, and it's not directly related to the `find()` function, but to the cursor of QTextEdit: `setTextCursor()` sets the *visible cursor* (the actual "caret" position and possible selection), which is exactly what `find()` needs to begin with: changing the position of a QTextCursor doesn't alter the actual position of the cursor in the widget (and its selection) until it's set back to the textedit. If you look at the `find()` docs of QTextDocument, you'll find that it requires a QTextCursor for its start position, and QTextEdit uses its *current* QTextCursor for that. – musicamante Dec 10 '20 at 16:39

1 Answers1

1

I found that textedit.textCursor() creates local copy of position and it doesn't change original position in QTextEdit.

You have to update position in QTextEdit using

textedit.setTextCursor(cursor) 

and then find() will find first t as you expect.


from PySide2.QtWidgets import QApplication, QTextEdit
from PySide2.QtGui import QTextCursor
import sys

app = QApplication(sys.argv)

textedit = QTextEdit()

cursor = textedit.textCursor()   # get local copy
cursor.insertText("test test test")
cursor.movePosition(QTextCursor.Start)
textedit.setTextCursor(cursor)   # update it

#textedit.insertPlainText("test test test")
#textedit.moveCursor(QTextCursor.Start)

textedit.show()

print(textedit.find("t"))  # first `t`
print(textedit.find("t"))  # second `t`

app.exec_()
furas
  • 134,197
  • 12
  • 106
  • 148
  • 1
    I know about this behavior and always thought of it as a feature (to not mess with the user's cursor while doing stuff in the background). This in mind it still is strange for me that one needs to use the "user's cursor" to make find() work – Koyagi Dec 10 '20 at 15:16